Storing Secrets in Kubernetes with OpenBao: Agent Injector vs CSI Provider vs External Secrets Operator

Compare the three main patterns for injecting OpenBao secrets into Kubernetes workloads — Vault Agent Injector, the Secrets Store CSI Driver, and External Secrets Operator — on security, overhead, rotation, and setup complexity.

5-9 minutes(1137 words)complex

Quick Navigation

Difficulty: Intermediate
Estimated Time: 15-20 minutes
Prerequisites: Basic Kubernetes knowledge, An OpenBao or Vault cluster reachable from the cluster, Familiarity with Kubernetes Secrets and RBAC

What You'll Learn

This guide compares the three dominant patterns for getting OpenBao secrets into Kubernetes workloads:

  • Agent Injector - Sidecar-based secret delivery with in-memory rotation
  • CSI Provider - Volume-mounted secrets via the Secrets Store CSI Driver
  • External Secrets Operator (ESO) - Syncing OpenBao secrets into native Kubernetes Secrets
  • Comparison Matrix - Security, overhead, rotation, complexity, and scalability side by side
  • Scoring - A weighted score for each option
  • Recommendations - Which pattern fits which workload, and why production clusters often combine them

Prerequisites

  • Basic Kubernetes cluster administration experience
  • An OpenBao (or Vault) cluster reachable from the Kubernetes cluster
  • Familiarity with Kubernetes Secrets, RBAC, and CRDs

Introduction

OpenBao — the open-source fork of HashiCorp Vault — is increasingly the secrets backend of choice for teams that want a vendor-neutral, community-governed store for credentials, PKI material, and encryption keys. The harder question is rarely "which secrets engine," it's "how do secrets actually get from OpenBao into a running pod." Three patterns dominate: an Agent Injector sidecar, the Secrets Store CSI Driver, and External Secrets Operator (ESO). Each makes a different trade-off between zero-trust security, operational overhead, and how much an existing application has to change to use it.

The Three Patterns

Agent Injector

A mutating webhook adds an init container and a sidecar to every annotated pod. The sidecar authenticates to OpenBao directly, renders secrets to an in-memory tmpfs volume as files, and keeps watching for renewal — reloading the file in place when a lease rotates, without the application needing to know anything about OpenBao. Secrets never pass through etcd and never sit on the API server.

CSI Provider

The Secrets Store CSI Driver runs as a per-node DaemonSet. A SecretProviderClass custom resource tells the driver's OpenBao provider what to fetch, and the driver mounts the result as a read-only volume backed by tmpfs at pod start. There's no per-pod sidecar — the driver is shared across every pod on the node — but there's also no built-in file-reload-on-rotation without an optional sync-to-Kubernetes-Secret add-on, and the application still needs a restart or a file-watcher to pick up rotated values.

External Secrets Operator (ESO)

A cluster-wide controller polls OpenBao (or Vault) on an interval defined by an ExternalSecret custom resource and writes the result into a native Kubernetes Secret object. Applications consume it exactly like any other Kubernetes Secret — as an env var or a mounted volume — with zero code or packaging changes. The trade-off is that the secret now exists in etcd, so its protection depends entirely on etcd encryption-at-rest and tight RBAC on the Secret resource.

Comparison Matrix

CritèreAgent InjectorCSI ProviderExternal Secrets Operator
PrincipeSidecar dans chaque podVolume monté via CSI driverSync vers K8s Secret natifs
Overhead ressourcesÉlevé (1 sidecar/pod, +50-100MB RAM/pod)Faible (pas de sidecar, driver partagé au niveau node)Faible (1 controller central)
Sécurité / Zero-trustSecrets jamais dans etcd, rotation en mémoireSecrets en tmpfs (RAM), pas dans etcdSecrets stockés en clair dans etcd (sauf chiffrement at-rest)
Rotation automatiqueNative, agent watch + reloadDépend du polling interval, pas de reload auto appPolling périodique, nécessite restart pod pour reload
Complexité setupWebhook + annotations par podDriver + SecretProviderClass CRDCRD ExternalSecret + SecretStore
Compat apps existantesApp doit lire des fichiers (pas toujours natif)Idem, montage fichierApp consomme un Secret K8s standard, zero refactor
Latence démarrage podInit container ajoute délaiRapide, driver déjà résidentSecret déjà sync avant déploiement
Observabilité/DebugLogs sidecar par podLogs driver niveau nodeController centralisé, events K8s clairs
Scalabilité (many pods)Coût linéaire (1 agent/pod)Driver partagé, plus léger à l'échelleUn seul controller, très scalable
Maturité écosystème OpenBaoInjector Vault mature, portage OpenBao récentProvider generic-CSI, dépend du support OpenBaoESO supporte Vault/OpenBao provider officiellement
Risque exposition secretsFaible (mémoire pod uniquement)Faible (tmpfs)Moyen-élevé (etcd, sauf encryption-at-rest + RBAC strict)

Score Global

Scored out of 10, weighted toward security and practicality:

InjectorCSIESO
Score8/107.5/107/10

The Injector leads on the security axis that matters most for a secrets pipeline — secrets never touch etcd — at the cost of a sidecar on every pod. CSI closes most of that resource gap while keeping the same tmpfs-only guarantee. ESO trades some of that isolation for near-zero application friction, which is why it still scores well despite depending on etcd encryption-at-rest to match the other two.

Recommendations by Context

  • Sécurité maximale, apps modernes → Agent Injector : meilleur choix si les apps peuvent lire des fichiers, et que le coût sidecar est acceptable.
  • Beaucoup de pods, besoin d'efficacité → CSI Provider : bon compromis sécurité/performance à l'échelle, sans sidecar par pod.
  • Legacy apps, besoin de simplicité, équipe déjà familière avec K8s Secrets → External Secrets Operator : le plus simple à adopter mais attention à chiffrer etcd at-rest et limiter le RBAC sur les Secret.

In many production setups, teams don't pick just one: ESO covers legacy and simple applications, while Injector or CSI handles sensitive workloads — payment processing, PII, cryptographic key material — where the extra operational cost buys a real reduction in blast radius.

Conclusion

There's no single right answer to "how should OpenBao secrets reach my pods" — the three patterns sit on a spectrum between zero-trust isolation and zero-friction adoption. Agent Injector and the CSI Provider both keep secrets out of etcd entirely, which matters most for regulated or high-value workloads; External Secrets Operator trades that isolation for compatibility with any application that already reads a Kubernetes Secret, provided etcd encryption-at-rest and RBAC are locked down. Most mature platform teams end up running more than one pattern side by side, matching the tool to the sensitivity of the workload rather than standardizing on a single mechanism cluster-wide.


Tags: #OpenBao #Vault #Kubernetes #SecretsManagement #CSIDriver #ExternalSecretsOperator #ZeroTrust #DevSecOps