Secrets in CI/CD

Secrets embedded in deployment scripts, GitHub Actions workflows, GitLab CI configuration or Jenkinsfiles can leak through both the repository and build logs.

When to use this guide

  • A token is embedded in .github/workflows/*.yml.
  • Credentials appear in a Jenkinsfile, .gitlab-ci.yml or deployment shell script.
  • A build-time token is written to a file instead of supplied through an environment variable.

Recommended approach

  • Use the CI/CD platform’s secret storage.
  • Keep only references in workflow files.
  • Review log masking, least-privilege permissions and rotation policies together.
  • For cloud deployments, prefer short-lived credential integration such as OIDC over long-lived static secrets where possible.

Examples

Before

yaml
steps:
  - name: Deploy
    run: |
      curl -H "Authorization: Bearer ghp_xxxxxxxxx" https://example.com/deploy

After

yaml
steps:
  - name: Deploy
    env:
      DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
    run: |
      curl -H "Authorization: Bearer ${DEPLOY_TOKEN}" https://example.com/deploy

Remediation steps for the owner

  1. Revoke exposed tokens first and replace them with new values.
  2. Remove actual secrets from workflows, Jenkinsfiles, CI configuration files and deployment scripts.
  3. Register the newly issued token or password in the CI/CD secret store.
  4. Keep only ${{ secrets.NAME }} or the platform’s equivalent reference syntax in files.
  5. For cloud provider access, assess whether OIDC federation can replace the static credential.
  6. Check recent run logs for exposure of the value.

Example instructions for the owner

  • “Remove tokens stored in workflow files and use GitHub Actions Secrets or your CI credential store.”
  • “Keep secret references, not literal values, in CI/CD configuration files.”
  • “Check recent build runs too, because their logs may retain secret values.”

Additional checks

  • Does log masking work?
  • Can external triggers, such as pull requests from forks, expose secrets?
  • Does the deployment token have excessive permissions?
  • Can OIDC or workload identity replace long-lived access keys?