OpenBao

Open-source secrets management platform (Vault fork). Includes automated initialization, auto-unseal CronJob, agent injector, Raft/file storage, Web UI, and ESO integration for centralized secret management.

Architecture

OpenBao Server - Secrets engine, auth backends, policies (:8200)
Agent Injector - Sidecar-based secret injection into pods
Init Job - One-time initialization: unseal keys, admin user, KV engine, ESO policy
Unseal CronJob - Runs every 5 min to auto-unseal after pod restarts
Web UI - Browser-based management interface

Attributes

Attribute Example Where It Impacts
namespace REQ openbao All manifests, service DNS, init-keys secret namespace
admin_password REQ ****** Init Job: userpass admin password
port 8200 helm-values.yaml API listener port, init/unseal jobs VAULT_ADDR
replicas 1 helm-values.yaml server replicas
pvc_size 10Gi helm-values.yaml persistent volume claim size
storageclass standard helm-values.yaml storageClassName
service_type ClusterIP helm-values.yaml K8s service type
mem_request / mem_limit 256Mi / 512Mi helm-values.yaml resources.requests/limits.memory
cpu_request / cpu_limit 250m / 500m helm-values.yaml resources.requests/limits.cpu
openbao_helm_version 0.25.6 helm/generate-yaml.sh chart version
openbao_app_version 2.5.1 Unseal CronJob container image tag

Init Job (init-job.yaml)

One-time Kubernetes Job that runs on first deploy to bootstrap OpenBao:

1. Wait for OpenBao to be reachable (30 retries, 10s interval)
2. Initialize OpenBao if not already initialized (key-shares=1, key-threshold=1)
3. Store unseal key + root token in K8s Secret ({name}-init-keys)
4. Unseal if sealed
5. Enable KV v2 secrets engine at secret/
6. Enable userpass auth + create admin user
7. Create ESO read-only policy (eso-read) for ExternalSecret access
RBAC:
ServiceAccount: {name}-init | Role: secrets read/create/update/delete
TTL: 600s | backoffLimit: 5

Auto-Unseal CronJob (unseal-cronjob.yaml)

Runs every 5 minutes to ensure OpenBao stays unsealed after pod restarts:

1. Check if OpenBao is reachable (10s timeout, exits cleanly if not)
2. If sealed: reads unseal key from {name}-init-keys K8s Secret, unseals
3. If already unsealed: skips
Schedule: */5 * * * * | concurrencyPolicy: Forbid | TTL: 120s

Links

Link Direction Generated Output
Prometheus → OpenBao Inbound Enables service-monitor.yaml for Prometheus metrics scraping
Istio → OpenBao Inbound Enables istio-injection label on namespace.yaml
ESO → OpenBao Inbound Triggers auto-seed Job in ESO template that populates OpenBao with all component secrets

Generated Files

File Condition Content
k8s/deploy/base/namespace.yaml Always Namespace definition with optional istio-injection label
k8s/deploy/base/init-job.yaml Always Init Job: initialize, unseal, enable KV/auth, create admin, ESO policy + RBAC
k8s/deploy/base/unseal-cronjob.yaml Always CronJob: auto-unseal every 5 min after pod restarts
k8s/deploy/base/service-monitor.yaml prometheus-openbao link ServiceMonitor for Prometheus metrics scraping
k8s/deploy/base/kustomization.yaml Always Kustomize resources + secretGenerator
k8s/deploy/base/secret/openbao.env Always Admin credentials (SOPS encrypted)
k8s/deploy/base/secret/registry.json Always Container registry credentials (SOPS encrypted)
helm/helm-values.yaml Always Helm values: storage, HA, injector, UI, resources, listeners
helm/generate-yaml.sh Always Helm template rendering script

Ports

Port Service Protocol
8200 OpenBao API + Web UI HTTP/HTTPS
8201 Cluster communication (Raft) TCP

Internal Endpoints

API: http://{name}.{namespace}.svc:8200
Web UI: http://{name}.{namespace}.svc:8200/ui
Init Keys Secret: {name}-init-keys (unseal-key, root-token)