OpenBao
OpenBao is the open-source fork of HashiCorp Vault, kept under the MPL 2.0 licence and run as an OpenSSF sandbox project under the Linux Foundation. A single Go server encrypts every secret before it reaches storage (integrated Raft or PostgreSQL), and it unseals at start from Shamir key shares or an auto-unseal key. Clients sign in through auth methods such as Kubernetes service-account tokens and get tokens scoped by path-based policies. It is free. It fits any team that wants Vault's API, KV, PKI, transit and dynamic secrets without the BSL licence.
OpenBao is a secrets manager. It stores API keys, database passwords and certificates encrypted at rest. It hands them to clients only after the client proves who it is and a policy allows the read, and it writes an audit trail of each access. It is the community fork of HashiCorp Vault that started after Vault moved off an open-source licence in 2023. Its API is largely the same as Vault's, so most Vault clients, tools and Kubernetes integrations work with it unchanged.
What it is
A single Go binary, bao. It acts as the server, the CLI and an optional agent/proxy. Its feature set comes from Vault: KV secrets (v1 and v2 with versioning), dynamic database credentials, a PKI engine, transit encryption-as-a-service, SSH signing, leases, revocation, audit devices and a web UI. OpenBao has since added features that were Enterprise-only in Vault. Namespaces for tenant isolation came in v2.3. Declarative self-initialization and the built-in static-key auto-unseal came in v2.4.
- Licence. MPL 2.0, the licence Vault had before the switch to the Business Source Licence.
- Governance. The project started under LF Edge. It moved to the Open Source Security Foundation (OpenSSF) as a sandbox project in June 2025, by a decision of its Technical Steering Committee. Copyright sits with LF Projects, LLC.
- Release line. The current line is v2.7 (v2.7.0 on 2026-09-23, v2.7.1 on 2026-10-01). The v2.6 line still gets patches (v2.6.4 shipped the same day as v2.7.1). Each patch release carries a batch of GitHub security advisories, so it pays to stay on a patched line.
- Distribution. Container images (
quay.io/openbao/openbao, plus a distroless variant since v2.6), Linux packages, and the official Helm chartopenbao/openbao(chart 0.30.4 ships app v2.7.1).
How it works
All data passes through the barrier, an AES-256-GCM encryption layer, before it reaches the storage backend. So a copy of the raw storage is useless without the keys. At start the server is sealed: it knows where its data is but cannot decrypt it. Unsealing gives it the root key. Either operators submit Shamir key shares, or an auto-unseal mechanism (a KMS plugin, the transit seal, or the static seal) supplies the key without a person.
After it unseals, every request carries a token. Clients get tokens from auth methods. The Kubernetes method trades a pod's service-account JWT for an OpenBao token. It checks the JWT with the TokenReview API of the cluster that issued it. Policies attached to the role decide which paths the token can read or write. Secrets engines mount at paths (kv/, pki/, transit/) and serve the request.
Step 1 of 3. At start the server reads the seal "static" block and loads the key named by current_key from its file or environment variable.
Three paths: auto-unseal at start, a Kubernetes-auth secret read by External Secrets, and a Raft snapshot to object storage.
Two consequences follow from this design. First, the unseal key and the snapshots are a pair. A snapshot without its key cannot be read, and losing the key loses the data. Second, OpenBao has no special trust in Kubernetes. Each cluster is just a TokenReview endpoint configured on an auth mount. One OpenBao server can serve many clusters with a separate mount, roles and policy for each.
When to use it
Reach for it when:
- Secrets are spread across
.envfiles, CI variables and Kubernetes Secrets, and a single source with audit logs and per-client policy is needed. - Several Kubernetes clusters need secrets, and each cluster should read only its own subtree.
- Short-lived credentials are wanted: dynamic database users, signed SSH certificates, or an internal PKI that issues short-TTL certificates.
- An existing Vault setup must leave the BSL licence while keeping the API, the CLI habits and the Helm-based install.
- Applications need encryption-as-a-service (transit) without holding the key material.
Skip it when:
- The workload already runs in one cloud and its managed secret store (AWS Secrets Manager, GCP Secret Manager, Azure Key Vault) is good enough. That removes a stateful service from the pager.
- There are a handful of static secrets and one cluster. SOPS-encrypted files in Git, or Sealed Secrets, cost far less to run.
- No one can own unseal, backup and upgrade work. A sealed or lost secrets server stops every deploy that depends on it.
- A vendor support contract is a hard requirement. OpenBao support comes from the community.
At a glance
Core concepts
- Seal / unseal: encrypted at rest until the root key is loaded from Shamir shares or an auto-unseal mechanism.
- Recovery keys: with auto-unseal,
bao operator initreturns recovery key shares. These authorize root-token generation and similar operations. They do not unseal. - Auth method: a login backend (Kubernetes, JWT/OIDC, AppRole, userpass, cert) mounted at a path. Each mount is configured on its own.
- Policy: HCL rules that grant capabilities (
read,list,create,update,delete,deny) on paths. - Secrets engine: a mounted backend such as KV v2, PKI, transit or database.
- Lease: a TTL on a token or dynamic secret, renewable and revocable.
- Namespace: a tenant boundary with its own mounts and policies. Since v2.6, a namespace can also have its own Shamir seal.
Key facts (v2.7)
| Item | Value |
|---|---|
| Licence | MPL 2.0 |
| Steward | OpenSSF sandbox project, Linux Foundation |
| Storage backends | Integrated Raft (HA), PostgreSQL (HA, read scaling on standbys since v2.7), PebbleDB (non-HA, since v2.7) |
| Removed in v2.7 | file storage backend; built-in cloud KMS and PKCS#11 seals (now plugins); built-in LDAP, Kerberos and RADIUS auth (now plugins) |
| Auto-unseal | static key, transit, KMS plugins from openbao-plugins |
| Helm chart | openbao/openbao, needs Kubernetes 1.30 or later |
| API port | 8200 (cluster traffic on 8201) |
OpenBao vs HashiCorp Vault
| Aspect | OpenBao | HashiCorp Vault |
|---|---|---|
| Licence | MPL 2.0 (OSI open source) | Business Source Licence 1.1 |
| Governance | Community TSC under the Linux Foundation / OpenSSF | IBM / HashiCorp |
| Namespaces | Included | Enterprise only |
| API and CLI | bao, Vault-compatible API paths and headers |
vault |
| Support | Community | Commercial contracts available |
How to integrate
Install with Helm (single node, Raft)
helm repo add openbao https://openbao.github.io/openbao-helm
helm install openbao openbao/openbao -n openbao --create-namespace -f values.yaml
# values.yaml: one Raft node with static-key auto-unseal
server:
ha:
enabled: true
replicas: 1
raft:
enabled: true
setNodeId: true
config: |
ui = true
listener "tcp" {
address = "[::]:8200"
cluster_address = "[::]:8201"
tls_disable = 1 # terminate TLS at the ingress, or set tls_cert_file
}
storage "raft" {
path = "/openbao/data"
}
seal "static" {
current_key_id = "unseal-1"
current_key = "file:///openbao/unseal/unseal-1.key"
}
service_registration "kubernetes" {}
volumes:
- name: unseal
secret:
secretName: openbao-unseal # created out of band: openssl rand -out unseal-1.key 32
volumeMounts:
- name: unseal
mountPath: /openbao/unseal
readOnly: true
Leave the chart's standalone mode alone on v2.7 or later. Its default config used the file backend, which v2.7.0 removed. Since then the chart's standalone default is PebbleDB.
Initialize once
kubectl -n openbao exec -it openbao-0 -- \
bao operator init -recovery-shares=1 -recovery-threshold=1
Store the recovery key and the initial root token outside the cluster. Revoke the root token after setting up admin auth.
Kubernetes auth for a remote cluster
bao auth enable -path=k8s-prod kubernetes
bao write auth/k8s-prod/config \
kubernetes_host=https://prod-api.example.com:6443 \
[email protected] \
token_reviewer_jwt="$(cat reviewer.jwt)" # SA bound to system:auth-delegator
bao policy write eso-prod - <<'EOF'
path "kv/data/prod/*" { capabilities = ["read"] }
path "kv/metadata/prod/*" { capabilities = ["read", "list"] }
EOF
bao write auth/k8s-prod/role/eso \
bound_service_account_names=external-secrets \
bound_service_account_namespaces=external-secrets \
policies=eso-prod ttl=1h
External Secrets SecretStore
apiVersion: external-secrets.io/v1
kind: ClusterSecretStore
metadata:
name: openbao
spec:
provider:
vault:
server: https://bao.example.com
path: kv
version: v2
auth:
kubernetes:
mountPath: k8s-prod
role: eso
serviceAccountRef:
name: external-secrets
namespace: external-secrets
Snapshot and restore
bao operator raft snapshot save openbao-$(date +%F).snap
bao operator raft snapshot restore openbao-2026-10-17.snap
In the GL stack
OpenBao 2.7.1 is the secret store for the clusters behind builddaily.io, paiddaily.io and the other products. It runs on the management cluster, one of three K3s clusters on Lima VMs on one Mac.
- Storage and unseal. It runs on integrated Raft storage. It unseals itself from a static unseal key at start, so a VM reboot does not wait for a person to enter key shares. Initialization produced one recovery share.
- Layout. Secrets live in a KV v2 engine at
kv/, with one subtree per cluster (kv/<cluster>/…). - Per-cluster access. Each client cluster (beta and prod) has its own Kubernetes auth mount. External Secrets on each cluster can read only that cluster's own
kv/<cluster>/*subtree. A compromised token on one cluster cannot read the other cluster's secrets. External Secrets writes the values into native Kubernetes Secrets, and Reloader restarts the workloads when they change. - Backup. A Raft snapshot is taken every night and written to the S3 backup store on SeaweedFS, next to the Postgres, Neo4j and Velero backups.
- Staleness. A secret-age exporter exposes how old each secret is, and an alert fires when one goes stale, so rotation gaps show up in monitoring instead of in an outage.
- Other uses. The Rancher local-admin break-glass password is kept in OpenBao, not in the cluster or in Git.
Gotchas
- v2.7 removed the
filebackend. Configs and older Helm values that usestorage "file"will not start on v2.7. The project published a migration guide from file to PebbleDB on Kubernetes. Raft and PostgreSQL users are not affected. - v2.7 moved cloud seals to plugins. The
awskms,gcpckms,azurekeyvault,ocikms,alicloudkmsandpkcs11seals are no longer built in. Install the matching plugin from openbao-plugins before the upgrade, or the server cannot unseal. The static and transit seals are still built in. - v2.7 moved LDAP, Kerberos and RADIUS auth to plugins. Any mounts of those methods need the plugin in place before the upgrade.
- Trailing-dot FQDNs. Because of a Go 1.27 change, the v2.7 PKI engine rejects names such as
example.com.. - The static seal moves the trust problem. The docs warn that it suits environments that already have a trusted source for the key. Anyone who can read the key file plus the Raft data can read every secret. Keep the key away from the snapshots and limit access to its Kubernetes Secret.
- Reviewer tokens expire. For a remote cluster, a short-lived
token_reviewer_jwtstops working when it expires, and every login on that mount fails. Use a long-lived service-account-token Secret for the reviewer, or let each client's own JWT do the review (each client then needssystem:auth-delegator). - Issuer validation is off by default on new Kubernetes auth mounts (
disable_iss_validation=true). Bind roles tightly to service-account names and namespaces. - Snapshots need Raft as primary storage. Snapshot save is not supported when Raft is used only for
ha_storage.
Risks
- Project health. A Siemens talk on the OpenBao blog notes that the IBM contributors who helped launch the fork left after IBM bought HashiCorp. The same talk puts the maintainer base at roughly 15 to 20 co-maintainers under a multi-vendor TSC. Activity is steady: a minor release every few months and working groups for namespaces, PKCS#11, scalability and supply chain. The project is still a sandbox, not an incubating or graduated one.
- Divergence from Vault. The API began as Vault's, and both projects keep changing. New Vault features and plugins will not appear in OpenBao on their own, and some third-party tools test only against Vault.
- Single point of failure. One OpenBao node is the secret source for every cluster. If it is sealed or down, existing Kubernetes Secrets keep working, but new secrets, rotations and logins stop. Keep snapshots tested and the unseal key recoverable.
- Security cadence. Recent patch releases each fixed several advisories (policy traversal, plugin path checks, Kubernetes auth renewal). Fall behind and those stay open.
- Lock-in. Low. The licence is open, the data can be exported through the API, and External Secrets can point at another provider without changes to the workloads.
Alternatives
- HashiCorp Vault: same design, commercial support, and Enterprise replication. Pick it when a support contract or Vault Enterprise features matter more than the licence.
- Infisical: a secrets platform with a dashboard aimed at developers, plus a Kubernetes operator. Pick it when teams want a web UI for editing secrets more than Vault-style engines and policies.
- SOPS (with age or a KMS): encrypted secret files kept in Git and decrypted at deploy time. Pick it for small setups with no server to run.
- Cloud secret managers (AWS Secrets Manager, GCP Secret Manager, Azure Key Vault): pick them when everything runs in one cloud and its IAM is already the identity layer.
Related
- External Secrets and Reloader: how secrets go from OpenBao into pods and roll the workloads.
- SeaweedFS and Velero: the backup store for the nightly snapshot, and cluster backups next to it.
- Keycloak, Rancher and Kyverno: sign-in, the cluster manager whose break-glass password lives here, and admission policy.
- K3s and Prometheus: the clusters it serves, and where the secret-age alerts land.
- Layer overview: security.
- Official: OpenBao docs, openbao/openbao releases, static seal, Kubernetes auth method.
