A common mistake is treating workflow security as a one-time setting instead of a per-action requirement. Another is assuming a single permission model fits every job. The safer approach is to maintain action-level permission data, review API usage, and update the workflow configuration whenever actions change. That keeps permissions aligned with real behavior.
Why token permissions are more fragile than teams expect
Token permissions in GitHub Actions are easy to misjudge because the effective authority of a workflow is not just the repository default, it is also shaped by the job, the event trigger, and any third-party action the workflow invokes. Teams often think in terms of “the workflow has read-only permissions” when the real question is whether each step only gets the minimum access it needs to complete its task.
A better mental model is that permissions are part of the workflow’s runtime design, not a one-time policy choice. If you add a new action, reuse a template, or change a trigger, the permission boundary may shift even if the repository settings do not. That is why GitHub Actions security behaves more like ongoing access governance than static configuration.
One useful way to verify the boundary is to compare each job’s actual API usage against the token scope it receives. If a job can publish packages, write releases, or modify repository contents, its permissions should be justified explicitly rather than inherited by habit. For background on non-human identity governance, the Ultimate Guide to NHIs is useful because it ties lifecycle, least privilege, and credential scope together in one model.
Where GitHub Actions teams usually go wrong
The most common mistake is treating all jobs as if they deserve the same token scope. Build, test, release, and deployment jobs have different risk profiles, so using one broad permission set for the whole workflow usually creates unnecessary write access. Another mistake is failing to revisit permissions after changing a workflow dependency, because a new action can silently expand what the workflow can do.
Teams also underestimate how much risk comes from third-party or reusable actions. If an action can read the token, call the GitHub API, or interact with external systems, then the trust boundary is wider than the visible YAML suggests. That is why supply-chain review matters as much as permission trimming, and why exposed workflow credentials can become a high-value target. The GitHub Action tj-actions Supply Chain Attack shows how compromised workflow components can turn CI/CD access into secret exposure at scale.
Another recurring failure is over-scoping the token “just in case” to avoid build breakage. That shortcut is operationally convenient but it creates a standing path to repository writes, release abuse, or lateral misuse if a workflow step is compromised. If your workflow needs a stronger scope only at a specific stage, isolate that stage rather than granting broad permissions across the whole pipeline.
Risk and Threat Considerations
GitHub Actions token scope is a real exposure point because a compromised workflow step, malicious dependency, or over-permissive action can turn automation into an attack path. The main risk is not only unauthorized repository change, but also secret access, release manipulation, and downstream compromise of any system the workflow can reach.
Failure mechanism: A workflow inherits more token authority than the step actually needs, or the permissions are not reviewed when actions, triggers, or job logic change. An attacker then abuses that excess scope to write content, exfiltrate secrets, or pivot into connected services.
Impact: The result can be source tampering, supply-chain compromise, leaked credentials, or unauthorized deployment actions. In practice, the blast radius is determined by the workflow’s token scope and by what the token can reach once a job is running.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP Non-Human Identity Top 10 and MITRE ATT&CK address the attack and risk surface, while CIS Controls v8, NIST CSF 2.0 and NIST SP 800-63 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP Non-Human Identity Top 10 | NHI-01 — Secrets and Credential Exposure | GitHub Actions tokens are identity-bearing credentials that can be overexposed in workflows. |
| NHI-03 — Privilege and Permission Management | The question is about excessive token permissions and least-privilege workflow access. | |
| Recommendation — Limit workflow token scope and rotate or revoke credentials when workflow trust changes. Apply least privilege per job and remove write permissions that the step does not need. | ||
| CIS Controls v8 | 6.3 — Access Control Management | Token permissions in CI workflows are an access-control problem requiring scoped authorization. |
| 16.11 — Establish and Maintain a Secure Software Development Workflow | GitHub Actions security depends on controlling workflow changes and third-party actions. | |
| Recommendation — Restrict automation accounts and tokens to the minimum access required for each workflow stage. Review workflow changes and third-party actions before they can expand token authority. | ||
| NIST CSF 2.0 | PR.AA — Identity Management, Authentication, and Access Control | Workflow tokens authenticate automation and must be managed as access-control assets. |
| GV.PO — Policy | Token permission standards need policy so teams do not improvise broad defaults. | |
| Recommendation — Scope automation credentials tightly and review access when workflow behavior changes. Define a workflow-permissions policy that requires least privilege and approval for exceptions. | ||
| MITRE ATT&CK | T1195 — Supply Chain Compromise | Compromised actions can abuse workflow trust to expand token use and steal secrets. |
| T1552 — Unsecured Credentials | Over-permissive workflows can expose secrets and tokens to malicious code or steps. | |
| Recommendation — Hunt for compromised actions and validate the provenance of reusable workflow components. Protect CI/CD secrets from workflow steps that do not strictly require access. | ||
| NIST SP 800-63 | IAL2 — Identity Assurance Level 2 | Automation credentials still need managed assurance and lifecycle discipline when they grant access. |
| Recommendation — Apply strong lifecycle and assurance controls to non-human credentials used by workflows. | ||
Practitioner Guidance
What to verify: Review permissions at the job level, not just the repository level, and confirm that each action’s documented API usage matches the scope it receives. Treat any workflow that can write contents, manage releases, or access secrets as a higher-risk path that deserves explicit approval.
Decision rule: If a workflow step does not need write access to complete its task, remove it. If a single step needs elevated authority, isolate that step and keep the rest of the job on the narrowest feasible scope so the elevated permission does not become the default for the whole pipeline.
What good looks like: Permission changes are version-controlled, reviewed when actions change, and validated against actual runtime behaviour. Teams can explain why each scope exists, which API calls justify it, and what would break if the permission were removed.
Practitioner takeaway: The safest GitHub Actions pattern is not “set permissions once,” but “continuously align token scope with current workflow behaviour,” because the most dangerous permission is the one that outlives the step that needed it.
Related resources from NHI Mgmt Group
- What do teams get wrong about securing GitHub Actions in large repository environments?
- What do teams get wrong about using OIDC in GitHub Actions?
- What do security teams get wrong about GitHub Actions supply chain risk?
- What do security teams get wrong about pinning GitHub Actions to commit hashes?