Vault Agent Injector vs Secrets Operator: A Kubernetes comparison
Vault Agent Injector vs Secrets Operator: A Kubernetes comparison
7 October 2025
Kilian Niemegeerts

This is part 5 of our HashiCorp Vault production series. With Vault running in our tooling cluster, we faced a crucial decision: how do we get those secrets into our application pods?
Series overview:
- Production Kubernetes Architecture with HashiCorp Vault
- Terraform Infrastructure for HashiCorp Vault on EKS
- External Secrets Operator: GitOps for Kubernetes Secrets
- Dynamic PostgreSQL Credentials with HashiCorp Vault
- Vault Agent vs Secrets Operator vs CSI Provider
- Securing Vault Access with Internal NLB and VPN
The 3 HashiCorp Vault Kubernetes integration options
HashiCorp provides three methods to get Vault secrets into Kubernetes:
- Vault Agent Injector
- Uses a mutating admission webhook to inject a sidecar container
- The sidecar authenticates with Vault and fetches secrets
- Secrets are written to a shared volume as files
- Vault Secrets Operator (VSO)
- Uses Kubernetes CRDs to declaratively manage secrets
- Fetches secrets from Vault and creates native Kubernetes Secrets
- Fully GitOps-compatible approach
- Vault CSI Provider
- Uses the Secrets Store CSI Driver
- Mounts secrets as ephemeral volumes during pod startup
- Another CRD-based approach
Our specific requirements
Before choosing, we had to consider our setup:
- Dynamic database credentials that rotate every hour (from part 4)
- GitOps-driven infrastructure using FluxCD
- External Secrets Operator already handling static secrets from Vault
- Zero application changes – developers shouldn’t need Vault knowledge
The key requirement? Automatic lease renewal for dynamic secrets.
Comparing the methods
With our requirements clear, we decided to focus our comparison on the Vault Agent Injector & the Vault Secrets Operator. This is how the options compare:
| Feature |
Vault Agent Injector |
Vault Secrets Operator |
|
| Secret delivery | Sidecar volume | Kubernetes Secret | |
| Dynamic secrets support | ✅ Yes | ❌ No (manual rotation) | |
| Lease management | ✅ Automatic | ❌ No | |
| GitOps-compatibility | ⚠️ Limited (via annotations) | ✅ Full (via CRDs) | |
| Use of native K8s secrets | ❌ No | ✅ Yes | |
| Dependency on Vault at pod startup | ✅ Yes | ❌ No | |
| Best application | Dynamic credentials | Static configuration |
Why We Chose HashiCorp Vault Agent Injector
The decision was straightforward once we looked at our dynamic database credentials requirement:
- Vault Secrets Operator was out – no automatic rotation for dynamic secrets
- Vault Agent Injector provides automatic lease management out of the box
Since we already use External Secrets Operator for static secrets (perfect for GitOps), we didn’t need VSO’s CRD approach. Vault Agent handles our dynamic credentials beautifully.
The Trade-offs We Accepted
Choosing Vault Agent Injector meant accepting:
- Resource overhead: Every pod gets an extra sidecar container
- Limited GitOps: Configuration via annotations, not CRDs
- Startup dependency: Pods can’t start if Vault is down
For dynamic database credentials with automatic renewal, these trade-offs were worth it. The automatic lease management alone prevents countless rotation-related incidents.
How HashiCorp Vault Agent Injector Works
Here’s the flow when using Vault Agent Injector:

The process is elegant:
- Application pod launches
- Agent-injector detects the pod and injects a Vault Agent sidecar
- Vault Agent authenticates using the pod’s ServiceAccount
- Agent requests secrets (like database credentials)
- Secrets are written to /vault/secrets
- Application reads secrets as regular files
Applications don’t need to know Vault exists – they just read files from a local path.
What’s Next?
With secrets flowing into our pods, how do we keep Vault itself secure? Our next post covers the internal NLB + VPN pattern for securing Vault access.
Continue reading: Kubernetes Vault Integration: Securing AWS Secrets with Internal NLB & VPN
Get the code: Our Vault configuration on GitHub
Sorry, the comment form is closed at this time.