Severity: Medium
Summary
Four workflows lack an explicit permissions declaration, causing the GITHUB_TOKEN to inherit the repository/organization default — which is typically read-write access to all scopes. This violates the principle of least privilege and increases the blast radius if any step in these workflows is compromised.
Affected Workflows
| Workflow File |
Trigger |
Permissions Needed |
Permissions Inherited (likely) |
.github/workflows/chromatic.yml |
push to staging |
contents: read |
Read-write to everything |
.github/workflows/storybook-tests.yml |
push (all branches) |
contents: read |
Read-write to everything |
.github/workflows/code-analysis.yml |
pull_request |
contents: read |
Read-write for internal PRs |
.github/workflows/tag-release.yml |
push to master |
contents: write |
Read-write to everything |
Already have explicit permissions (correct):
publish.yml — contents: read, packages: write
storybook-deployment.yml — contents: read, pages: write, id-token: write
claude.yml — contents: read, pull-requests: read, issues: read, id-token: write
claude-code-review.yml — contents: read, pull-requests: read, issues: read, id-token: write
Impact
- When no
permissions key is declared, the GITHUB_TOKEN inherits the repository's default permission setting. For repositories/organizations that have not explicitly restricted this, the default grants read-write access to all scopes.
- If any step in these workflows is compromised (e.g., via an unpinned third-party action like
chromaui/action@latest, or a malicious dependency pulled in by npm install), the attacker would gain write access they should never have had — including the ability to push commits, create releases, modify packages, and more.
- The
tag-release.yml case is notable because it legitimately needs contents: write (for creating tags/releases) — but even this workflow should not have implicit access to packages: write, pull-requests: write, issues: write, etc.
Recommended Fix
Add explicit minimal permissions to each workflow:
# chromatic.yml — only reads source code
permissions:
contents: read
# storybook-tests.yml — only reads source code and runs tests
permissions:
contents: read
# code-analysis.yml — only reads source code and runs linters
permissions:
contents: read
# tag-release.yml — needs to create tags and GitHub Releases
permissions:
contents: write
Context
Identified during a modular security audit. The fact that 4 other workflows already have explicit permissions shows the team follows this practice — these 4 were likely missed.
Found by automated security audit — VULN-08
Severity: Medium
Summary
Four workflows lack an explicit
permissionsdeclaration, causing theGITHUB_TOKENto inherit the repository/organization default — which is typically read-write access to all scopes. This violates the principle of least privilege and increases the blast radius if any step in these workflows is compromised.Affected Workflows
.github/workflows/chromatic.ymlpushtostagingcontents: read.github/workflows/storybook-tests.ymlpush(all branches)contents: read.github/workflows/code-analysis.ymlpull_requestcontents: read.github/workflows/tag-release.ymlpushtomastercontents: writeAlready have explicit permissions (correct):
publish.yml—contents: read,packages: writestorybook-deployment.yml—contents: read,pages: write,id-token: writeclaude.yml—contents: read,pull-requests: read,issues: read,id-token: writeclaude-code-review.yml—contents: read,pull-requests: read,issues: read,id-token: writeImpact
permissionskey is declared, theGITHUB_TOKENinherits the repository's default permission setting. For repositories/organizations that have not explicitly restricted this, the default grants read-write access to all scopes.chromaui/action@latest, or a malicious dependency pulled in bynpm install), the attacker would gain write access they should never have had — including the ability to push commits, create releases, modify packages, and more.tag-release.ymlcase is notable because it legitimately needscontents: write(for creating tags/releases) — but even this workflow should not have implicit access topackages: write,pull-requests: write,issues: write, etc.Recommended Fix
Add explicit minimal
permissionsto each workflow:Context
Identified during a modular security audit. The fact that 4 other workflows already have explicit permissions shows the team follows this practice — these 4 were likely missed.
Found by automated security audit — VULN-08