Skip to main content
RunBook Academy

← All checklists in Secrets, PKI & Certificates

Quarterlycicd-secret-handling

CI/CD Secret Handling Checklist

24 items ·16 critical ·7 warn ·1 info

How to use this checklist

A delivery pipeline touches more credentials in a week than most engineers touch in a year, and it does so unattended. This review runs once a quarter across the repositories that can deploy to production, and it follows a credential rather than a system: where it comes from, which jobs can see it, what it is written into, and what it leaves behind when the job ends.

Do it with the pipeline owner present and a terminal open. Almost every item here has a command, and the commands are deliberately crude greps over the workflow directory rather than elegant policy queries. That is the point: you are looking for the one workflow somebody added in a hurry, and a policy engine that only inspects the main branch will not find it.

Where the numbers come from

Workflow behaviour is read from the files in the repository, on the default branch and on every branch that can trigger a deployment. Cloud-side trust is read from the identity provider rather than from the pipeline, because the trust policy is the half that decides who is believed and it lives outside the repository entirely.

Image evidence comes from a published image, not from the build file. The history of an image is the record of what was actually passed to the build, and it survives every later instruction that appeared to clean up. Infrastructure state evidence comes from the state file itself: pull it, list the attribute names, and look at what the configuration has been recording all this time.

Three answers cannot be produced by a command. Whether the fork opt-in settings are disabled, whether the team standard records the limits of output suppression, and whether the response to a committed credential begins with rotation are questions about settings pages and documents. Name the person who read them.

Access this needs

Read access to the repositories and their settings pages, read-only credentials that can describe the deployment role and its trust policy, permission to pull a published image, and read access to the remote state backend. Nothing here requires the ability to run a deployment or to assume the deployment role. If you find yourself needing production write access to answer an item, the item has been written wrongly and the pipeline is answering a question about itself.

What the review produces

A dated report per repository listing every item, its disposition, and the command output that supports it. Alongside it: the current inventory of stored secrets with owners and scopes, the list of workflows using the fork-context trigger with their justifications, and any accepted risks with expiry dates. It goes to the pipeline owner and the security owner. Anything found in a log, an artefact or an image history during the review is treated as a live disclosure and rotated the same day, not recorded as a finding for the next cycle.

Sign-off

  • Reviewer: ________________ Date: ___________
  • Platform owner: ___________ Date: ___________
  • Security owner: ___________ Date: ___________

Every critical item must pass. A failing critical item means the pipeline is not trusted to hold production credentials, and the correct response is to remove the credential from it until the item is closed. Record the date, the reviewer, and the disposition of every item that did not pass.

Critical16 items

  1. grep -rn "id-token" .github/workflows/
  2. aws iam get-role --role-name gha-deploy --query "Role.AssumeRolePolicyDocument"
  3. aws iam get-role --role-name gha-deploy --output json | jq -r ".Role.AssumeRolePolicyDocument.Statement[].Condition"
  4. grep -rn "pull_request_target" .github/workflows/
  5. grep -rn -A4 "actions/checkout" .github/workflows/
  6. grep -rn "add-mask" .github/workflows/
  7. grep -rnE "base64|urlencode|--data-urlencode" .github/workflows/
  8. terraform state pull | jq -r ".resources[].instances[].attributes | keys[]" | sort -u | head -n 40
  9. grep -rnE "ephemeral|_wo *=|_wo_version" *.tf
  10. grep -rn "encrypt" backend.tf
  11. grep -rl "ANSIBLE_VAULT" group_vars host_vars
  12. docker history --no-trunc registry.example.com/app:2026.08.26
  13. grep -rn "mount=type=secret" Dockerfile
  14. grep -rnE "^RUN rm|rm -f .*(key|pem|token)" Dockerfile
  15. gitleaks detect --source . --no-banner --redact --log-opts="--all"

Warning7 items

  1. grep -rnE "actions/upload-artifact|actions/cache" .github/workflows/
  2. grep -rnE "terraform output" .github/workflows/
  3. grep -rn "TF_LOG" .github/workflows/
  4. grep -rn "no_log" roles/ playbooks/
  5. grep -rnE "lookup\(" playbooks/
  6. gh api repos/example-org/platform | jq -r ".security_and_analysis"
  7. gh secret list --repo example-org/platform

Info1 item