Overview
OpenBao is the Linux Foundation’s open-source (MPL-2.0) fork of HashiCorp Vault: an identity-based secrets engine with a Vault-compatible API and CLI, covering KV v2 storage, dynamic secrets, PKI and transit encryption. This template deploys one OpenBao server with integrated raft storage on a persistent volume and auto-unseal, so the server comes back unsealed on its own after every restart with no operator action. If you are choosing between catalog templates: OpenBao is the Vault-compatible engine for workloads that need dynamic secrets, PKI, transit or existing Vault tooling, while Infisical is an application-secrets workflow platform with a team-oriented web UI. The two solve different problems and can run side by side.What Gets Created
static seal mode the unseal key lives in a secret you create; the root token and recovery keys exist only in the output of the one-time initialization you run.
Prerequisites
What must exist before install depends on the seal mode (seal.type). The default is static.
Static Seal
One opaque secret must exist before you install. Secrets are org-level, so no GVC flag is involved.Create the unseal-key secret
plain whose payload is a 32-byte key. OpenBao accepts the key hex-encoded, which is what openssl rand -hex 32 produces:seal.static.secretName to this name. Use printf, not echo — echo appends a newline that becomes part of the key.Keep a copy of the key outside Control Plane
cpln secret reveal SECRET_NAME -o yaml (a bare reveal prints only a summary table) and store a copy in a second system, such as a password manager or offline vault.KMS Auto-unseal Setup
Skip this section if you keep the defaultstatic seal. The awskms and gcpckms modes need no unseal-key secret: the server encrypts and decrypts its barrier key through your KMS key, and the workload identity reaches the key through a Control Plane cloud account, so no cloud credential is stored in the container or in your values.
- AWS KMS
- GCP Cloud KMS
cpln-connector policy), so the identity is usable as soon as it is created and no post-install step is needed.Create or pick a symmetric KMS key
seal.aws.kmsKeyId to the key ARN (a key ID or alias also works) and seal.aws.region to the key’s region.Register a Cloud Account
seal.aws.cloudAccountName to its name.Create a key-scoped IAM policy
seal.aws.policyName to the policy name. These are the three actions the awskms seal uses; grant them on the one key, never with a broad managed policy.Install with seal.type set to awskms
--set seal.type=awskms together with the four seal.aws.* values. The server boots ready and uninitialized, exactly as in static mode — continue with First Run.Installation
Install the chart from the marketplace registry, pointing the default static seal at the unseal-key secret you created:seal.type and the matching seal.aws.* or seal.gcp.* keys instead of seal.static.secretName — see KMS Auto-unseal Setup.
Or follow the instructions for your preferred method:
UI
CLI
Terraform
Pulumi
Configuration
Each block below is the shipped default for that part ofvalues.yaml.
OpenBao Server
2.6.x line on purpose: OpenBao 2.7 moves the built-in KMS auto-unseal mechanisms into external plugins, so a blind bump would break the awskms and gcpckms seal modes. Raise maxMemory for large secret sets or heavy PKI use.
maxCpu to minCpu may not exceed 4:1, and the defaults sit exactly at that limit. Raising maxCpu without raising minCpu crosses it and is rejected when the workload is applied.Seal and Auto-unseal
seal.type selects exactly one mode; only that mode’s sub-block is used and the others are ignored.
Storage
helm upgrade. Uninstalling deletes the volume set (a final snapshot is kept for 7 days), and a reinstall comes up uninitialized.
Access
publicAccess.enabled: true and upgrade the release when you want the API and web UI on the *.cpln.app endpoint. A change to either access knob can take several minutes to take effect — re-test before concluding it did not apply.
Connecting
bao CLI is present in the container with BAO_ADDR preset, so any bao command runs through cpln workload exec without extra flags. Verify the server is up:
Initialized false and Sealed true — that is the expected state until you initialize it.
First Run
The server boots reachable but uninitialized. Initialize it exactly once; from then on every restart auto-unseals.Initialize the server
-recovery-shares and -recovery-threshold to change the split.Store the output somewhere safe
Confirm the server unsealed itself
Initialized true and Sealed false means the seal mechanism is working; the server will return to this state on its own after every restart.Log in
bao CLI from your own machine:http://localhost:8200/ui/, choose the Token method and paste the root token. From a terminal with bao installed, point it at the tunnel and log in — bao login prompts for the token, which keeps it out of your shell history:Set up real authentication and retire the root token
userpass, oidc or approle), write policies, and then revoke the initial root token as upstream recommends. A new root token can be generated later with the recovery keys if it is ever needed. Only after this is in place consider publicAccess.enabled: true.Operations
Backing Up
The chart schedules no backups of its own. Two paths are available: Volume set snapshot. Snapshots the raft volume as a whole. Take one before upgrades or risky changes:bao CLI on your machine through the port-forward tunnel while logged in with a sufficiently privileged token. It needs no file transfer out of the container. This command follows the upstream raft snapshot procedure and the chart’s raft configuration but has not been exercised against this template — rehearse it on a throwaway release first:
static mode, keep the unseal-key secret backed up alongside it (see Static Seal); in the KMS modes, keep the KMS key.
Restoring a Backup
- Raft snapshot. Restore into a release that is initialized, unsealed and running under the same seal key the snapshot was taken under — the same static secret value, or the same KMS key. Through the tunnel, logged in:
bao operator raft snapshot restore openbao.snap. Restoring across a different seal key is outside what is documented here. - Volume set snapshot.
cpln volumeset snapshot restorerestores a volume from a snapshot taken above; checkcpln volumeset snapshot restore --helpfor its required--snapshot-name,--locationand--volume-indexflags. This command has not been exercised against this template. - Accidental uninstall. Uninstalling deletes the volume set, and the final snapshot it takes is retained for 7 days. That snapshot, plus the unseal-key secret (which uninstall does not touch), is the only way back.
Scaling and Availability
- The template deploys a single replica with no
replicasknob; raft runs with one member, so there is no failover. - A node failure reschedules the server and reattaches the same volume, and the server unseals itself on the way back up. The exposure is a short restart gap, not data loss or a manual unseal.
- The volume set is snapshotted only when it is deleted (final snapshot, kept 7 days); use Backing Up for point-in-time copies.
Troubleshooting
Workload never becomes ready and cpln logs returns nothing
Workload never becomes ready and cpln logs returns nothing
RELEASE_NAME-openbao stays not ready indefinitely, and cpln logs '{gvc="GVC_NAME", workload="RELEASE_NAME-openbao"}' --limit 50 --since 10m returns zero lines.Cause: seal.static.secretName names a secret that does not exist, so the container is never started. The reason is visible only in status.versions[].message:cpln workload force-redeployment RELEASE_NAME-openbao --gvc GVC_NAME.Health endpoint returns 501 and bao status says Initialized false
Health endpoint returns 501 and bao status says Initialized false
GET /v1/sys/health returns 501 and bao status reports Initialized false, Sealed true.Cause: this is a fresh server that has not been initialized yet. The readiness probe deliberately treats the uninitialized and sealed states as healthy so the API and UI stay reachable for the one-time initialization — restarting the workload will not change it.Fix: run bao operator init once as described in First Run.gcpckms workload crash-loops with PermissionDenied cloudkms.cryptoKeys.get
gcpckms workload crash-loops with PermissionDenied cloudkms.cryptoKeys.get
cpln helm install reported success, but RELEASE_NAME-openbao restarts repeatedly and cpln logs '{gvc="GVC_NAME", workload="RELEASE_NAME-openbao"} |= "PermissionDenied"' --limit 50 --since 10m shows PermissionDenied … cloudkms.cryptoKeys.get.Cause: the identity’s service account has not been granted access on the crypto key, or was granted only cryptoKeyEncrypterDecrypter. OpenBao also calls cloudkms.cryptoKeys.get at startup and exits without it. The chart attaches no IAM binding of its own, so this grant is always a post-install step.Fix: grant both roles/cloudkms.cryptoKeyEncrypterDecrypter and roles/cloudkms.viewer on the key to the service account named by the identity’s status.objectName — see KMS Auto-unseal Setup. The workload recovers on its own. Confirm the identity is healthy with cpln identity get RELEASE_NAME-openbao-identity --gvc GVC_NAME -o yaml (status.gcp.usable).awskms server is ready but bao operator init fails with a KMS error
awskms server is ready but bao operator init fails with a KMS error
awskms mode the workload is ready and uninitialized, and bao operator init fails with an AWS KMS access or key error instead of printing recovery keys.Cause: seal.aws.kmsKeyId or seal.aws.region does not match the key, or the IAM policy named in seal.aws.policyName does not grant kms:Encrypt, kms:Decrypt and kms:DescribeKey on it. A wrong key does not stop the server from booting; it surfaces at the first seal operation.Fix: check the identity with cpln identity get RELEASE_NAME-openbao-identity --gvc GVC_NAME -o yaml, correct the policy or the values, and upgrade the release. The server has not been initialized, so nothing is lost.Logs warn that the Auto Unseal mechanism has moved into an external plugin
Logs warn that the Auto Unseal mechanism has moved into an external plugin
awskms or gcpckms mode logs Support for this Auto Unseal mechanism has been moved into an external plugin.Cause: an upstream deprecation notice. On the pinned 2.6.1 image the built-in KMS seals still work; the notice is why the image is pinned to the 2.6.x line.Fix: none needed. Do not bump openbao.image to 2.7 or later without arranging the external seal plugin — the KMS seal modes would stop working.Logs mention raft FSM db file has wider permissions than needed
Logs mention raft FSM db file has wider permissions than needed
raft FSM db file has wider permissions than needed appears in the logs on startup.Cause: cosmetic. The data directory is made group-writable so the non-root openbao user can use the volume.Fix: none needed.Important Notes
- Static mode: the unseal-key secret must exist before install, and it is write-once. A missing secret wedges the deployment silently; a lost or changed key makes all stored data unrecoverable. Back the key up outside Control Plane.
- Run
bao operator initonce after install and store the output — the recovery keys and root token are printed a single time, to your terminal only, and recovery keys cannot unseal the server. - Do not switch
seal.typeafter initialization — changing modes requires an OpenBao seal migration, not a values change. gcpckmsneeds its key grant applied after install — the workload crash-loops oncloudkms.cryptoKeys.getuntil both roles are granted on the key, then recovers on its own.- Keep
openbao.imageon the 2.6.x line — 2.7 moves the KMS seals into external plugins and would breakawskmsandgcpckms. - Private by default — initialize and configure authentication through
cpln port-forward, then setpublicAccess.enabled: trueto expose the API and web UI on the canonical endpoint. - Data survives restarts and upgrades; uninstall deletes the volume set (a final snapshot is kept for 7 days) and leaves your unseal-key secret in place. A reinstall starts uninitialized.
- No backups are scheduled — take volume set or raft snapshots yourself, and remember a snapshot is only readable under the same seal key.