GitHub Actions: Secrets, Permissions, Security, and OIDC

Secure GitHub Actions workflows with permissions, environments, secrets, masking, fork safety, and OpenID Connect for cloud auth.

View
StandardDetailedCompact
Export
Copy the compact sheet, download it, or print it.
Download
`D` dense toggle · `C` copy all

Permissions and secrets

Use least privilege and avoid unsafe secret handling.

Set least-privilege token permissions

Limit the default GITHUB_TOKEN scope.

yamlANYpermissionsGITHUB_TOKEN
yaml
permissions:
  contents: read

Restrict permissions at the workflow or job level unless write access is truly needed.

Grant write access only where needed

Elevate token permissions on a specific job.

yamlANYpermissionsjob
yaml
jobs:
  release:
    permissions:
      contents: write

Use per-job permissions so publish jobs can write while test jobs remain read-only.

Expose a secret as an environment variable

Use the `secrets` context in step env.

yamlANYsecretsenv
yaml
- name: Login
  env:
    API_TOKEN: ${{ secrets.API_TOKEN }}
  run: ./scripts/login.sh

Secrets are automatically masked in logs, but still avoid printing them.

Mask a dynamic sensitive value

Hide a generated or fetched secret from logs.

bashANYmasklogssecurity
bash
echo "::add-mask::$TOKEN"

Mask runtime-generated credentials or sensitive values before any command could log them.

Use protected environments for deploys

Require approval and environment-scoped secrets.

yamlANYenvironmentapprovals
yaml
jobs:
  deploy:
    environment: production

Environments help gate deploys and scope secrets to staging, production, or other targets.

OIDC and fork safety

Use short-lived cloud auth and avoid dangerous pull_request setups.

Enable OIDC token issuance

Grant `id-token: write` when using cloud federation.

yamlANYoidcpermissions
yaml
permissions:
  id-token: write
  contents: read

OIDC lets workflows exchange a short-lived identity token for cloud credentials without storing static secrets.

Configure AWS credentials via OIDC

Use the AWS credentials action without long-lived keys.

yamlANYawsoidcdeploy
yaml
- uses: aws-actions/configure-aws-credentials@v4
  with:
    role-to-assume: arn:aws:iam::123456789012:role/github-actions-deploy
    aws-region: us-east-1

Pair this with an IAM role trust policy that trusts GitHub's OIDC provider and claims.

Authenticate to Google Cloud with OIDC

Use workload identity federation for GCP.

yamlANYgcpoidcauth
yaml
- uses: google-github-actions/auth@v2
  with:
    workload_identity_provider: projects/123456789/locations/global/workloadIdentityPools/pool/providers/provider
    service_account: deployer@example-project.iam.gserviceaccount.com

This avoids storing long-lived JSON keys in repository secrets.

Do not expose secrets to untrusted forks

Avoid unsafe patterns for public repo pull requests.

yamlANYforkspull_requestsecurity
yaml
on:
  pull_request:

Be careful with workflows that run untrusted code from forks. Avoid combining privileged tokens or secrets with unreviewed pull request code paths.

Recommended next

No recommendations yet.