How do you secure GitHub Actions workflows that build and deploy from pull requests without exposing production credentials?
Quick Answer
Secure workflows use least-privilege `GITHUB_TOKEN` permissions, avoid exposing secrets to untrusted pull request code, pin third-party actions, and prefer OIDC-based cloud federation over long-lived cloud keys. Deployment should run only from trusted refs or protected environments after review gates pass.
Detailed Answer
Think of a company mailroom where outside contractors can submit packages for inspection. You want the mailroom to test the package, but you do not hand the contractor the master key to the building. Pull requests are similar: they are valuable input, but their workflow code may be untrusted. A secure GitHub Actions design separates inspection from privileged deployment.
GitHub Actions workflows run code from repositories and can access tokens, artifacts, caches, and secrets depending on event type and configuration. The security model gets risky when a workflow triggered by pull request content can read secrets or write to protected branches, registries, or cloud accounts. Least privilege means each workflow and job receives only the permissions it needs, such as read-only contents for tests and short-lived identity for deployments.
Internally, the GITHUB_TOKEN is created for workflow runs and scoped by repository and workflow permissions. Secrets are withheld from many untrusted fork scenarios, but mistakes happen when teams use dangerous events, run untrusted scripts after checkout, or pass secrets into build steps. OIDC, or OpenID Connect, lets GitHub mint a short-lived identity token that a cloud provider exchanges for temporary credentials with conditions on repository, branch, environment, and workflow.
In production, teams split pipelines: pull request workflows lint, test, and build without secrets; merge-to-main workflows publish artifacts; deployment workflows require protected environments, reviewers, and narrow cloud roles. They pin actions by SHA, restrict workflow permissions, avoid writing secrets to logs, validate artifact provenance, and protect caches from untrusted key poisoning. Monitoring includes failed deployments, unexpected permission grants, and audit logs for environment approvals.
The gotcha is that pull_request_target runs In the base repository, which can expose privileged tokens if it checks out and executes attacker-controlled code from the PR. Senior engineers know when to use it only for metadata actions, never for running untrusted build scripts. They also treat third-party actions like dependencies: pin them, review them, and update them deliberately.