When I first built a deployment pipeline, I stored database passwords and API keys in the platform's encrypted secrets store and assumed that was sufficient. I've since realized that encryption at rest doesn't solve the problem of credentials being static and long-lived. If a key is exposed or forgotten after a job runs, it may remain valid indefinitely, and incomplete audit logging can make misuse difficult to detect. I'm considering a setup where workflows authenticate with short-lived, dynamically issued credentials that expire after deployment. How are you handling this in practice? Do you rely on built-in CI/CD secrets, or use OIDC and a secrets manager to avoid keeping long-lived credentials in the pipeline platform?
4 Answers
OIDC is the key piece, but the trust policy needs to be narrowly scoped. Give pull requests, approved branches, and production environments different identities and permissions. A production deployment should not be able to use the same identity as an untrusted pull request, and the workflow should retrieve production secrets directly from the cloud secret manager instead of copying them into CI secrets.
Another pattern is a GitHub App or workload identity that mints tokens on demand, usually with a short lifetime such as an hour. You may still have one private key to protect, but its use can be isolated to the token-minting service. In Kubernetes, an external-secrets controller can retrieve and synchronize narrowly scoped secrets while handling temporary authentication for workloads.
For a multi-cloud or hybrid setup, keep secrets in Vault and let the runner authenticate with its JWT or OIDC identity. That avoids storing Vault login credentials in the CI platform as well. Vault can then issue narrowly scoped, short-lived credentials for each job. If everything is in AWS, Secrets Manager may be simpler, but Vault is more portable.
This approach has worked well for multi-cloud environments because the CI system only proves its workload identity, while Vault controls which secrets and leases that workload can receive.
The runner should authenticate using its OIDC or JWT identity rather than a stored client ID and secret whenever the platform supports that option.
A common AWS setup is to use the CI platform’s OIDC integration to assume a role, then retrieve secrets from AWS Secrets Manager. The workflow doesn’t need a long-lived AWS access key; it receives a short-lived identity token and only gets the permissions assigned to that role.
Other cloud platforms support the same OIDC or workload-identity pattern, so a separate secrets-manager hop isn’t always necessary if the provider can issue the required temporary credentials directly.
The secrets manager still contains the underlying application secrets, so access policies and rotation are important there too. OIDC mainly avoids putting permanent cloud credentials in the CI system.

It’s also worth questioning whether every value is truly a secret or whether the deployment can use an identity-based API instead. Reducing the number of secrets is often more effective than just storing them more securely.