Grant least-privilege CI permissions at both workflow and job level
This is a principle
A reusable technical claim: something I would want true in any of my work.
Claim. Declare the minimum token permissions a workflow needs, explicitly - set a restrictive baseline at the workflow level, then narrow (or selectively elevate) per job, so each job holds only what it actually uses.
When to apply. Any CI system with scoped tokens (GitHub Actions permissions,
etc.). Broadly applicable.
Why. CI tokens run with whatever scope you grant; the platform default is
often far broader than needed, so a compromised action or dependency in any job
inherits write access to your repo, releases or pages. Setting a tight
workflow-level baseline and granting elevated scopes to only the one job that
needs them (e.g. the deploy job gets pages: write/id-token: write, everything
else stays read-only) contains blast radius. Prefer OIDC (id-token) over
long-lived stored secrets where the platform supports it.
Snippet.
permissions: # workflow-level baseline: minimal
contents: read
jobs:
deploy:
permissions: # only this job elevates
pages: write
id-token: write
How enforced. Explicit permissions: blocks at both levels; no reliance on
inherited defaults. Related: Pin GitHub Actions to full commit SHAs (same
supply-chain threat model).
BacklinksΒΆ
The following pages link to this page: