GitHub Actions security
GitHub Actions security depends on workflow triggers, token permissions, runner boundaries, and the trustworthiness of executed code.
What it means
GitHub Actions security depends on workflow triggers, token permissions, runner boundaries, and the trustworthiness of executed code. A workflow can combine repository access and secret credentials with attacker-influenced input. Review event semantics and data handling rather than assuming every job operates with the same trust.
A practical example
A maintainer separates untrusted pull-request testing from privileged release tasks. Expressions influenced by contribution content are passed as data instead of inserted directly into shell scripts, and third-party actions receive deliberate version and permission review.
What to check
Restrict workflow token permissions, examine privileged triggers, and protect release environments. Review action dependencies and self-hosted runner isolation, especially when jobs execute code from external contributors.
A common pitfall
A workflow file looking harmless does not make invoked scripts safe. Repository content, artifacts, and action dependencies can all introduce executable behavior into a privileged job.
Think it through
Why inspect a job's trigger as well as its commands?
Answer: The trigger determines whose code and data can reach the job, which changes whether its privileges are appropriate.
Separate contribution testing from release authority
A workflow can execute code from contributors, dependencies, and third-party actions. The security question is which of those inputs can influence a job that holds credentials or deployment permissions. A test job running less-trusted code should not inherit production authority merely because the repository also has trusted release jobs. Evaluate the trigger and execution context together.
Repository token permissions, runner isolation, action references, and environment protections are different controls. Pinning an action reference can reduce unexpected changes in the referenced action, but it does not establish that the pinned code is safe. Masking a secret in logs does not prevent code with access to that secret from using it elsewhere.
A fictional pull-request workflow
An academy accepts proposed documentation changes from outside contributors. Its validation job builds the submitted site with restricted permissions and no production secrets. A separate release process operates on reviewed inputs and has a clear deployment boundary. The team checks that artifacts from the less-trusted job cannot be substituted into release without the intended validation.
It also reviews self-hosted runners carefully. A runner that persists between jobs can retain files or state from earlier execution, making isolation assumptions important. Treat the runner as a system requiring maintenance and a trust model, rather than a disposable label in a configuration file.
Review without exploiting
In a repository you control, draw the path from an outside contribution to a production deployment. Mark where code executes, which identities are available, and where approval occurs. Identify one unnecessary permission and propose a narrower alternative. Verify workflow syntax and behavior in a harmless test environment; avoid exposing real credentials simply to demonstrate that a job could access them.
Related concepts
References & further reading
Original explanations, with primary references for deeper study.
OWASP: GitHub Actions Security