Secrets Management in CI/CD Pipelines
Treat secrets like temporary keys, not permanent passwords. Your CI/CD pipeline should fetch them just-in-time from a central vault, never storing them in code. The biggest footgun is storing secrets as long-lived environment variables in the CI tool itself.
WHY IT EXISTS: CI/CD pipelines need privileged access to build, test, and deploy applications. Hardcoding secrets like API keys or database passwords in code or config files is a massive security risk. Secrets management provides a secure way for automated systems to get the credentials they need without exposing them to developers or storing them insecurely.
THE MENTAL MODEL: Think of a secret manager as a digital valet. Your CI/CD job doesn't own the car keys (the secret). Instead, it presents its identity to the valet (the secrets manager), who verifies it and hands over a key that only works for a specific car (the target resource) and for a very short time. The job uses the key, and then it expires. The key is never written down or stored in the job's configuration.
HOW IT WORKS: Instead of storing a secret directly in the CI/CD system, you store a credential that lets the pipeline authenticate with a dedicated secrets management service like AWS Secrets Manager or HashiCorp Vault. During a run, the job uses its workload identity to request a short-lived, dynamically generated secret from the manager. This secret is injected into the job's environment, used for its task, and then automatically revoked or expired when the job finishes. This process avoids storing static secrets in git or CI/CD platform variables.
WHEN TO USE IT: Use this for any non-human access to a protected resource. This includes database credentials for integration tests, API keys for third-party services, and cloud provider credentials for deploying infrastructure. The goal is to eliminate static, long-lived secrets from your entire software development lifecycle and replace them with dynamic, auditable, just-in-time access.
WHEN NOT TO USE IT: The principle of not storing secrets in code is universal. However, the overhead of a dynamic secrets system might be excessive for a simple, one-off script with no sensitive access. For any recurring, automated process, especially one that is part of a production deployment chain, dynamic secrets management is the standard. For local development, other tools might be used, but they should still prevent secrets from being committed to source control.
ONE CANONICAL EXAMPLE: A Kubernetes deployment pipeline. The CI/CD runner, operating within a pod, uses its Kubernetes Service Account token to authenticate with a secrets manager. It requests temporary database credentials. The secrets manager generates a new username and password for the database with a 5-minute lifespan and returns them to the runner. The runner uses these credentials to run database migrations. After 5 minutes, the credentials automatically become invalid. They were never checked into git or stored permanently in the CI system.
Read the original → cheatsheetseries.owasp.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.