Adds a ClusterIssuer (selfSigned) + Certificate, mounts the resulting secret into the OpenBao pod, and switches the listener config from tls_disable=1 to a TLS-enabled listener. UI/API is now served over https://<node-ip>:30200 instead of plain HTTP. Also updates ClusterSecretStore/bootstrap Job to use https + trust the self-signed cert via caProvider/BAO_SKIP_VERIFY. Co-authored-by: Copilot <[email protected]>
openbao-gitops
Deploys OpenBao (standalone mode, file storage backend) as the cluster's central secret management backend, and wires up the External Secrets Operator (ESO) to read from it via Vault's Kubernetes auth method.
This chart wraps the official openbao-helm
chart as a dependency and adds:
- A self-signed TLS certificate (via cert-manager) that OpenBao terminates itself, so both the UI and API are served over HTTPS
- A
ClusterSecretStore(ESO CRD) pointing at the OpenBao service - A one-time bootstrap
Job(disabled by default) that enables the Kubernetes auth method, a read-only policy, and a role bound to ESO's ServiceAccount
TLS
OpenBao terminates HTTPS itself using a certificate issued by a dedicated
ClusterIssuer/openbao-selfsigned (cert-manager, selfSigned type - no
external CA involved). The UI/API is reachable at
https://<node-ip>:30200 (NodePort, same pattern as ArgoCD).
Because the certificate is self-signed, browsers will show a trust warning
- this is expected.
ExternalSecret/ClusterSecretStoretraffic from ESO trusts it automatically viacaProvider(pointing at the sameopenbao-tlsSecret cert-manager creates), so no manual CA import is needed for that path.
If you add/replace a node, or want a different reachable hostname, add it to
tls.ipAddresses / tls.dnsNames in values.yaml and cert-manager will
reissue the certificate automatically.
Prerequisites
- ESO must already be installed in the cluster (deployed separately via the
apps-in-appsrepo) with a ServiceAccount namedeso.serviceAccountName(default:external-secrets) ineso.namespace(default:external-secrets). - cert-manager must already be installed (used for the self-signed TLS cert, see below).
Deployment & manual init/unseal
OpenBao (like Vault) cannot be auto-initialized/unsealed when using file storage without a KMS auto-unseal mechanism, so this part is a manual, one-time step per environment:
-
Deploy this chart (via ArgoCD, see
apps-in-apps) - or locally:helm dependency update . helm upgrade --install openbao . -n openbao --create-namespace -
Initialize OpenBao (save the unseal keys and root token securely, e.g. in a password manager - they are NOT stored anywhere in git):
kubectl exec -n openbao -it openbao-0 -- bao operator init -
Unseal (repeat with 3 of the 5 unseal keys from step 2):
kubectl exec -n openbao -it openbao-0 -- bao operator unseal -
Store the root token as a Secret so the bootstrap Job can use it:
kubectl create secret generic openbao-root-token \ -n openbao --from-literal=token=<root-token-from-step-2> -
Enable the bootstrap Job and re-sync (e.g.
--set bootstrap.enabled=truevia the ArgoCD Application's Helm parameters, or invalues.yaml). It enables the KV v2 engine, the Kubernetes auth method, theeso-readpolicy and theeso-rolerole bound to the ESO ServiceAccount. -
Confirm the
ClusterSecretStore/openbaobecomesValid:kubectl get clustersecretstore openbao -o wide
After this, any namespace can create an ExternalSecret referencing the
openbao ClusterSecretStore to pull secrets from OpenBao's secret/ KV
mount.
Note: after a pod restart (upgrade, node reschedule, etc.) OpenBao comes back up sealed and must be unsealed again with the keys from step 2 unless you later configure an auto-unseal mechanism (e.g. Transit, cloud KMS) - out of scope for this initial setup.
Configuration
See values.yaml. Key settings:
| Key | Description | Default |
|---|---|---|
openbao.server.dataStorage.size |
PVC size for OpenBao's data | 10Gi |
openbao.server.dataStorage.storageClass |
StorageClass, empty = cluster default | "" |
eso.namespace / eso.serviceAccountName |
Where ESO runs and which ServiceAccount to bind | external-secrets |
eso.kvMountPath |
KV v2 mount path used by the ClusterSecretStore | secret |
bootstrap.enabled |
Toggle the one-time auth/policy bootstrap Job | false |