DevOps Peach

Security (DevSecOps) · Secret management · Lesson 6 of 6

Secrets in CI/CD pipelines

Pipelines hold deploy rights, which makes them valuable targets; use the CI platform's secret store, scope secrets to environments, keep them out of logs and replace long-lived keys with OIDC for short-lived cloud credentials.

Practice interactively →

Why pipelines are sensitive

Pipelines usually can push images, change infrastructure and deploy to production. Whoever takes over a pipeline (through a malicious pull request, a compromised third-party action or a token leaked in logs) gains those rights.

The CI platform's secret store

Platform Where secrets live
GitHub Actions Repository, environment and organization secrets
GitLab CI CI/CD variables (masked, protected)
Jenkins Credentials plugin
Azure DevOps Secret variables, variable groups linked to Key Vault
# GitHub Actions
jobs:
  deploy:
    environment: production          # environment secrets, may require approval
    steps:
      - run: ./deploy.sh
        env:
          API_TOKEN: ${{ secrets.API_TOKEN }}
gh secret set API_TOKEN --env production    # enter the value at a prompt, not in history
gh secret list

Platforms mask secret values in logs, but masking only matches the exact string: base64 or substrings slip through. Never echo secrets and do not enable set -x in steps that use them.

OIDC instead of long-lived keys

Instead of storing AWS_SECRET_ACCESS_KEY in secrets, the workflow requests an OIDC token from GitHub; the cloud checks the token (which repo, branch, environment) and issues credentials valid for tens of minutes.

sequenceDiagram
  participant W as Workflow
  participant G as GitHub OIDC
  participant C as AWS STS / Entra ID
  W->>G: request ID token (permissions: id-token: write)
  G-->>W: token with repo, ref, environment claims
  W->>C: exchange token for a role
  C-->>W: short-lived credentials
permissions:
  id-token: write
  contents: read
steps:
  - uses: aws-actions/configure-aws-credentials@v4
    with:
      role-to-assume: arn:aws:iam::111122223333:role/gha-deploy
      aws-region: ap-southeast-1

The role's trust policy must restrict sub, for example repo:example-org/myapp:environment:production, so other repos cannot borrow it.

Good practice

Practice interactively →