When I first moved from a traditional ops role into a DevSecOps-focused workflow, the thing that surprised me most wasn’t the tooling — it was how many different places credentials could hide. Between CI/CD pipelines, container images, Kubernetes manifests, and third-party integrations, a “simple” password or token can end up scattered across a dozen systems without anyone realizing it.
This post is my breakdown of how I approach credential management across the DevSecOps lifecycle, from local development all the way through to production.
What Is Credential Management in a DevSecOps Context?
Credential management is the practice of securely storing, distributing, rotating, and auditing sensitive values — passwords, API keys, tokens, certificates — throughout the software delivery pipeline. In DevSecOps specifically, this means credentials need to be handled securely not just in the application, but in every automated step that touches the code: build, test, package, deploy, and run.
flowchart TD
A[Developer Workstation] --> B[Source Control]
B --> C[CI Pipeline]
C --> D[Build & Test]
D --> E[Container Registry]
E --> F[Deployment / Orchestration]
F --> G[Runtime Environment]
H[Secrets Manager] -.injects at runtime.-> C
H -.injects at runtime.-> F
H -.injects at runtime.-> G
Notice that in a properly designed pipeline, the secrets manager injects credentials at each stage rather than credentials being baked into the artifacts themselves. That’s the core principle I build around.
Principle 1: Centralize Secrets in a Dedicated Manager
I never let credentials live in scattered .env files, CI variables, or config maps if I can avoid it. Centralizing them in a tool like HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault gives me:
- A single source of truth
- Fine-grained access policies
- Automatic rotation support
- Full audit logging of who accessed what, and when
# Example: reading a database credential from Vault
vault kv get -field=password secret/prod/database
Principle 2: Inject Credentials at Runtime, Not Build Time
One mistake I made early on was baking credentials into a Docker image during build. That meant anyone who pulled the image — intentionally or not — had the secret. Now I inject secrets at runtime through environment variables sourced from the secrets manager, or through mounted volumes that aren’t part of the image layers.
# Kubernetes example: injecting a secret at runtime
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
If you’re working with containers regularly, it’s worth reviewing Docker and Kubernetes fundamentals, since secret injection patterns differ significantly between the two.
Principle 3: Apply Least Privilege Everywhere
Every service, pipeline stage, and human user should only have access to the specific credentials it needs — nothing more. I map this out explicitly for each pipeline stage rather than assuming broad access is fine “because it’s internal.” This overlaps heavily with IAM Best Practices for DevSecOps, which I’d recommend reading alongside this post.
Principle 4: Automate Secret Rotation
Manual rotation doesn’t scale, and it’s the first thing that gets skipped when a team is busy. I automate rotation wherever the secrets manager supports it, and for services that don’t support automatic rotation, I build a scheduled job that rotates and updates references across dependent systems. I cover the specific mechanics in Secret Rotation Best Practices.
Principle 5: Scan for Credentials at Every Pipeline Stage
I treat secret scanning as a required gate, not an optional check:
- Pre-commit: catch secrets before they’re pushed
- CI pipeline: scan the codebase and dependencies
- Container build: scan image layers for embedded secrets
- Pre-deployment: verify no plaintext secrets exist in manifests
# Example CI step using gitleaks
gitleaks detect --source . --exit-code 1
Principle 6: Audit and Monitor Access Continuously
Every credential access should be logged, and I review these logs regularly — not just after an incident. Unusual access patterns (a service account suddenly pulling credentials it’s never touched before) are often the earliest sign of compromise.
Common Mistakes in Credential Management
- Storing secrets as plain CI/CD environment variables instead of a secrets manager
- Sharing a single service account credential across multiple applications
- Baking secrets into container images during build
- Forgetting to revoke credentials for decommissioned services
- Treating secrets management as a one-time setup instead of an ongoing process
Best Practices Checklist
| Stage | Practice |
|---|---|
| Development | Use local secrets manager or vault dev server, never hardcode |
| CI/CD | Inject via pipeline secrets integration, scan every build |
| Container build | Never bake secrets into image layers |
| Deployment | Runtime injection via secrets manager |
| Production | Automated rotation, full audit logging |
FAQs
What’s the difference between a secrets manager and a password manager? A password manager is designed for human use — storing and autofilling credentials for people. A secrets manager is built for machine-to-machine access, with APIs, access policies, and automated rotation designed for applications and pipelines.
Do I need a secrets manager for a small project? Even small projects benefit from centralizing secrets rather than scattering them across config files, but the overhead of a full enterprise secrets manager might not be justified. A lightweight option like Doppler or even encrypted environment files with strict access control can be a reasonable middle ground.
How do I handle credentials for third-party integrations? Store them the same way you’d store internal credentials — in your secrets manager, scoped narrowly, and rotated on a schedule. Never let third-party integration keys sit in plaintext config.
Can secret scanning replace a secrets manager? No, they solve different problems. Scanning catches accidental exposure; a secrets manager prevents the exposure from having a place to happen in the first place. I use both together.
Conclusion
Secure credential management in DevSecOps isn’t about picking one tool — it’s about building a consistent pattern across every stage of the pipeline: centralize secrets, inject them at runtime, apply least privilege, automate rotation, scan continuously, and audit relentlessly. Once that pattern is in place, credentials stop being the weak link they so often are in fast-moving DevOps environments.
