SmokyZoneandCopilot e27524177c Use global.tlsDisable=false instead of duplicating BAO_ADDR
Setting a second BAO_ADDR via extraEnvironmentVars produced two entries
with the same name in the container env list. kubectl itself warns
this 'may be dropped when using apply', and in practice the live
StatefulSet kept only the first (http) value, leaving the pod stuck
NotReady. The chart already exposes global.tlsDisable specifically to
drive BAO_ADDR/health-check scheme - use that instead.

Co-authored-by: Copilot <[email protected]>
2026-09-18 20:33:12 +02:00
2026-09-18 19:50:46 +02:00
2026-09-18 19:50:46 +02:00
2026-09-18 19:50:46 +02:00

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/ClusterSecretStore traffic from ESO trusts it automatically via caProvider (pointing at the same openbao-tls Secret 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-apps repo) with a ServiceAccount named eso.serviceAccountName (default: external-secrets) in eso.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:

  1. Deploy this chart (via ArgoCD, see apps-in-apps) - or locally:

    helm dependency update .
    helm upgrade --install openbao . -n openbao --create-namespace
    
  2. 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
    
  3. Unseal (repeat with 3 of the 5 unseal keys from step 2):

    kubectl exec -n openbao -it openbao-0 -- bao operator unseal
    
  4. 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>
    
  5. Enable the bootstrap Job and re-sync (e.g. --set bootstrap.enabled=true via the ArgoCD Application's Helm parameters, or in values.yaml). It enables the KV v2 engine, the Kubernetes auth method, the eso-read policy and the eso-role role bound to the ESO ServiceAccount.

  6. Confirm the ClusterSecretStore/openbao becomes Valid:

    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
S
Description
OpenBao is a Secret Vault to store Secrets safely outside of Kubernetes.
Readme
93 KiB
Languages
Go Template 100%