GitGuardian's State of Secrets Sprawl 2026 counted 28.65 million new hardcoded secrets in public GitHub commits during 2025 — up 34% year over year, the largest single-year jump ever recorded. AI-service credentials surged 81% to 1.275 million, and the report found 24,008 secrets sitting in MCP configuration files alone. Every one of those numbers is a team that stored a credential wherever was convenient and paid for it later.
A self-hosted git-push PaaS cannot afford to be one of those teams, because its convenience default becomes every tenant's security posture. Sooner or later the platform has to answer: where do tenant secrets actually live, and how do they get into the cluster? The three names that come up are External Secrets Operator, self-hosted Vault, and Infisical — but comparing them as three interchangeable options is a category error. ESO holds zero secrets. It is a sync engine, not a store. The real decision is two choices, not one: which sync layer moves secrets into Kubernetes, and which store holds them outside it.
Here is the verdict up front, with the reasoning and the tables below:
| Team profile | Sync layer | Store | Why in one line |
|---|---|---|---|
| Default for a multi-tenant PaaS | ESO | OpenBao | Backend-agnostic CRDs plus the deepest dynamic-secrets engine with free namespaces |
| Simplest ops, mostly static secrets | Infisical operator | Infisical | Fewest moving parts: one MIT-licensed store with its own native sync |
| Tenants may bring their own backend later | ESO | OpenBao now | ESO's SecretStore abstraction keeps the store swappable without rewriting app manifests |
Note the second column of the default row says OpenBao, not Vault. That substitution is load-bearing and explained below — Vault Community Edition's license bars embedding it in a product you sell, so "self-hosted Vault" as a PaaS backend means the Linux Foundation fork in practice.
What a git-push PaaS needs from a secrets backend
Before scoring anything, here are the five criteria the later tables grade against. They come straight from what tenant secrets demand on a platform you operate for other people:
- Self-hostable end to end. No forced dependency on a managed cloud secrets API. Every component must run on machines you own, because the PaaS's whole pitch is that tenants don't outsource trust to someone else's SaaS.
- A Kubernetes-native CRD interface. Tenants declare what they need in YAML; controllers reconcile. Anything requiring dashboard click-throughs or host-level agents per app doesn't survive contact with a git-push workflow.
- Multi-tenant isolation. One tenant's misconfigured policy must not be able to read another tenant's credentials. Flat shared namespaces with careful naming conventions are not isolation.
- A rotation story. Static strings that live forever are how 64% of valid secrets first seen in 2022 were still active in early 2026, per that same GitGuardian report. Short-lived or easily rotated credentials beat permanent ones.
- Bounded operational cost. The secrets stack sits on the critical path of every tenant deploy. Its maintenance — backups, upgrades, on-call — has to fit a small platform team, not a dedicated security org.
Now measure the default most platforms start with — plain Kubernetes Secrets — against that list. A K8s Secret is base64-encoded, not encrypted; anyone with etcd access, a broad RBAC grant, or backup-file access reads every tenant credential in the fleet. There is no rotation primitive, no per-tenant cryptographic boundary, and no audit trail beyond the apiserver log. Envelope encryption via a KMS provider (which you should enable regardless — more on that below) fixes the at-rest half and none of the lifecycle half. "Store it in a Kubernetes Secret and call it done" fails criteria 3 and 4 outright, which is why a platform serving real tenant credentials can't quietly keep relying on it.
What each contender actually is
External Secrets Operator (ESO) is a CNCF incubating project, currently on its v2.x line, that syncs secrets from external backends into native Kubernetes Secrets. You declare a SecretStore (credentials for one backend) and ExternalSecret objects (which remote keys map to which K8s Secret keys); the controller polls or watches and keeps the cluster copy fresh. PushSecret goes the other direction. ESO itself stores nothing — it supports dozens of providers including Vault, Infisical, and every major cloud secrets manager, plus a Vault dynamic-secret generator for leased credentials.
Its value is the abstraction: apps consume ordinary K8s Secrets while the platform team can swap backends by editing the store, not the app.
Self-hosted Vault, honestly, means OpenBao. HashiCorp re-licensed Vault under the Business Source License 1.1 in August 2023, and the BSL's competing-offering clause bars embedding Vault Community Edition inside a product sold to third parties — which is exactly what a PaaS's built-in tenant-secrets feature is. The practical self-hosted Vault-API option is OpenBao, the Linux Foundation fork of Vault's last MPL-2.0 release: drop-in API-compatible, on its 2.6.x line as of mid-2026, with namespaces — the multi-tenancy primitive Vault gates behind Enterprise — free and GA since mid-2025.
What you get is Vault's full depth: KV storage, dynamic database and cloud credentials, PKI, transit encryption, and Kubernetes auth. What you pay is Vault's full ops surface: Raft storage, unsealing (or auto-unseal wiring), and upgrades on a stateful cluster that every deploy depends on.
Infisical is the MIT-licensed store built to be the simpler answer: API server, dashboard, CLI (infisical run -- injects secrets into any process), and SDKs, backed by Postgres and Redis. For Kubernetes it ships its own native operator with sync, push, and dynamic-secret CRDs, plus an agent injector that mounts secrets into pods without landing them in etcd at all. The catch, documented in detail when we priced the Doppler comparison earlier this year: RBAC, SSO, secret versioning, and automatic rotation live behind Pro at $18/month per identity — and "identity" counts every machine account alongside every human, even on a fully self-hosted instance. The free core is genuinely free; the governance features a multi-tenant platform eventually wants are not.
The comparison that matters: two tables, not one
Score the sync layer and the store separately, against the five criteria above.
Sync layer: ESO vs Infisical operator vs Vault Secrets Operator (VSO). VSO is HashiCorp's own vendor-native sync — VaultStaticSecret/VaultDynamicSecret CRDs reconciled into K8s Secrets — and since it speaks the Vault API it runs against OpenBao as well as Vault.
| ESO | Infisical operator | VSO | |
|---|---|---|---|
| Backend-agnostic | Yes — dozens of providers behind one CRD shape | No — Infisical only | No — Vault API only |
| Bidirectional (push back to store) | Yes (PushSecret) | Yes (push CRDs) | No — sync is one-way into the cluster |
| Dynamic/leased secrets | Yes via Vault generator and provider support | Yes, native dynamic-secret CRDs | Yes — it's the native path for Vault dynamic engines |
| Maturity | CNCF incubating, v2.x, widest adoption | Younger, single-vendor, moving fast | Single-vendor, tracks Vault releases |
| Fits criterion 2 (CRD-native) | Yes | Yes | Yes |
ESO wins this table on exactly one axis — backend-agnosticism — and that axis is the whole game for a platform. A tenant that outgrows the default store, or an operator migrating stores in year two, changes a SecretStore, not every app manifest. The native operators win on depth with their own store and lose the moment the store changes.
Store: OpenBao vs Infisical. Both clear criterion 1 (fully self-hostable, no cloud dependency) and both can sit behind ESO.
| OpenBao | Infisical | |
|---|---|---|
| License | MPL-2.0, Linux Foundation | MIT core, commercial ee/ directory |
| Dynamic secrets depth | Deepest in class: databases, cloud IAM, PKI, SSH, transit | Present and growing; narrower engine catalog |
| Multi-tenant isolation | Namespaces: free, GA, per-namespace policies/auth/seal | Projects + environments; fine-grained RBAC needs Pro |
| Stateful footprint | Raft-integrated (no external DB) plus unseal ceremony | Postgres + Redis to operate (or provide managed) |
| Audit | Per-request audit devices, compliance-oriented | Audit logs; advanced governance needs Pro |
| Fits criterion 4 (rotation) | Leased dynamic credentials are the native model | Rotation exists; automatic rotation needs Pro |
Read the two tables together and the shape of the answer emerges: OpenBao is the deeper store with the heavier ceremony, Infisical is the lighter store with the commercial ceiling, and ESO is the layer that lets you choose between them without marrying either at the app layer.
The three realistic pairings, priced in ops terms
Nobody runs a sync layer without a store, so here are the combinations that actually get deployed, with honest costs.
ESO + OpenBao: the default for a multi-tenant PaaS. You operate one OpenBao cluster with per-tenant namespaces and one ESO deployment whose ClusterSecretStore points at it. Tenants write ExternalSecret manifests; the platform owns unseal/upgrade/backup cadence on the OpenBao side (Raft snapshots, auto-unseal via a local KMS or HSM path, quarterly minor upgrades) and almost nothing on the ESO side beyond chart upgrades. The payoff is the full dynamic-secrets catalog: tenant Postgres credentials become short-lived leases instead of permanent strings, which is criterion 4 satisfied structurally rather than by policy.
The price is Vault-family operational seriousness — unseal key custody and Raft quorum health are now your problem on the fleet's most critical dependency. For a platform team already running stateful infrastructure, this is familiar work; for a two-person team that has never operated Raft, it is the steepest learning curve of the three options.
ESO + Infisical: uniform CRDs over the simpler store. Same ESO interface for tenants, but the SecretStore points at a self-hosted Infisical instance backed by Postgres and Redis — infrastructure you may already run for the PaaS itself. Ops reduce to standard database hygiene: backups, restore drills, failover checks.
Two caveats keep this from being the default. First, ESO's Infisical provider has historically trailed the Vault and cloud providers in maturity — verify its current stability tier before committing a fleet to it, because an alpha-grade provider on the deploy critical path is a bad trade. Second, you now have two Kubernetes operators in the secrets path if you also use Infisical-native features, which muddies the "one CRD shape" story ESO is supposed to buy you.
Infisical native (operator + store, no ESO): fewest moving parts. One vendor, one operator, one dashboard, plus genuinely useful extras ESO can't give you: infisical run -- for build-time injection, the agent injector for pods that should never see etcd-backed Secrets at all. Prior cost analysis put steady-state ops for a small production instance at single-digit engineering hours a month — backup verification, changelog skims, periodic failover checks. The ceiling is governance and depth: per-tenant RBAC strictness, SSO, and automatic rotation push you toward per-identity Pro billing (which crosses managed-vendor pricing fast once machine identities pile up), and the dynamic-secret catalog is narrower than OpenBao's. This is the right pick when tenant secrets are overwhelmingly static strings and the team values simplicity over depth.
One hygiene note applies to all three: every ESO-based pairing still materializes secrets as native K8s Secrets, which land in etcd. Enable envelope encryption at rest (KMS provider) on every cluster no matter which pairing you choose — the sync layer solves lifecycle and sprawl, not storage encryption. Only the agent-injector path avoids etcd entirely, and only for the pods that use it.
Recommendation and migration path
Default to ESO as the uniform CRD interface with OpenBao as the store. The reasoning order matters: pick ESO first, because backend-agnostic ExternalSecret manifests are the decision that compounds — every tenant manifest written against ESO is a manifest that survives a future store migration. Then pick OpenBao as the first store behind it, because free namespaces plus the deepest dynamic-secret catalog is the combination that satisfies all five criteria without a commercial tier. If your tenant mix is simple enough that static secrets plus minimal ops win, run Infisical native instead — but write the manifests against ESO's Infisical provider rather than Infisical-only CRDs where you can, so the day you need Vault-grade dynamic secrets is a SecretStore edit, not a manifest rewrite.
The migration path is the proof of the architecture. Moving from OpenBao to Infisical (or back) under ESO means: stand up the new store, replicate the secret tree, point the SecretStore at it, and let the controller re-sync. Apps never change; no tenant action required. Compare that to migrating off a native-operator-only setup, where every manifest in every tenant namespace names the old system's CRDs. That switching cost is the real price tag on this decision, and it dwarfs the few hours a month of steady-state ops either store needs.
Secrets sprawl keeps growing — 34% last year, with AI-agent credential types leading the surge — because the convenient default keeps winning. A PaaS gets to choose its tenants' default. Choose the one where the sync interface outlives the store, the store holds leases instead of permanent strings, and no SaaS vendor sits anywhere in the trust path.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.



