OpenBao Integration#
Support level This integration is validated and supported in Reloader Enterprise. Community usage is possible, but without continuous validation or SLA
This guide shows how to automatically restart Kubernetes workloads when OpenBao secrets change using Stakater Reloader.
What is OpenBao?#
OpenBao is an open-source, community-driven fork of HashiCorp Vault, managed by the Linux Foundation. It was created after HashiCorp changed Vault's license from MPL 2.0 to BSL 1.1. OpenBao maintains API compatibility with Vault, making it a drop-in replacement for most use cases.
Integration Patterns#
| Pattern | How Secrets Arrive | Rotation | Reloader Compatibility | Guide |
|---|---|---|---|---|
| External Secrets Operator | ESO syncs to K8s Secret | ESO refresh interval | Best fit | ESO Guide |
| OpenBao Secrets Operator | BSO syncs to K8s Secret | BSO refresh interval | Best fit | BSO Guide |
| CSI Driver | CSI mounts files + syncs to K8s Secret | CSI rotation interval | Works with secretObjects |
CSI Guide |
| CSI Driver (File-Based) | CSI mounts files only (no K8s Secret) | CSI rotation interval | Works via SecretProviderClassPodStatus | CSI File Guide |
Architecture Overview#
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β OpenBao + Reloader Architecture β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β OpenBao Server (openbao namespace): β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β OpenBao β β
β β ββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββ β β
β β β KV v2 Engine β β Kubernetes Auth β β AppRole Auth β β β
β β β secret/myapp β β (k8s SA tokens) β β (RoleID/SecretID)β β β
β β ββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β Application Namespace: β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Secret Sync (ESO / BSO / CSI) β β
β β ββββββββββββββββββββ ββββββββββββββββββββ β β
β β β Operator CRDs βββββΊβ K8s Secret β β β
β β β (SecretStore, β β (app-secrets) β β β
β β β VaultAuth, etc.)β β match: "true" β β β
β β ββββββββββββββββββββ ββββββββββββββββββββ β β
β β β β β
β β βΌ β β
β β ββββββββββββββββββββ ββββββββββββββββββββ β β
β β β Stakater ReloaderβββββΊβ Application Pod β β β
β β β Detects change β β Rolling restart β β β
β β ββββββββββββββββββββ ββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Prerequisites#
- Kubernetes cluster (v1.19+)
- Helm v3+
- OpenBao (OSS)
- OpenBao CLI (
bao) installed locally - Stakater Reloader installed
- kubectl configured with cluster access
Install Stakater Reloader#
helm repo add stakater https://stakater.github.io/stakater-charts
helm install reloader stakater/reloader --namespace reloader --create-namespace
Common Setup Steps#
Step 1: Install OpenBao#
# Add OpenBao Helm repo
helm repo add openbao https://openbao.github.io/openbao-helm
helm repo update
# Install OpenBao
helm install openbao openbao/openbao -n openbao --create-namespace \
--set "server.dataStorage.size=1Gi" \
--set "injector.enabled=false"
Note: The injector is disabled because this guide uses ESO, BSO, or CSI to sync secrets. Enable it if you also need OpenBao Agent sidecar injection.
Wait for the pod to start (it will be Running but not Ready until unsealed):
kubectl wait --for=jsonpath='{.status.phase}'=Running pod/openbao-0 -n openbao --timeout=180s
Step 2: Initialize and Unseal OpenBao#
# Initialize OpenBao (using 1 key share for simplicity; use more in production)
kubectl exec -n openbao openbao-0 -- bao operator init \
-key-shares=1 \
-key-threshold=1 \
-format=json > openbao-init.json
Important: Save openbao-init.json securely. It contains the unseal key and root token.
# Extract unseal key and root token
OPENBAO_UNSEAL_KEY=$(cat openbao-init.json | jq -r '.unseal_keys_b64[0]')
OPENBAO_ROOT_TOKEN=$(cat openbao-init.json | jq -r '.root_token')
# Unseal OpenBao
kubectl exec -n openbao openbao-0 -- bao operator unseal "$OPENBAO_UNSEAL_KEY"
OpenBao should now show Sealed: false. Wait for the pod to become Ready:
kubectl wait --for=condition=ready pod/openbao-0 -n openbao --timeout=30s
Step 3: Configure OpenBao CLI#
Set up the bao CLI locally:
# Port-forward for local CLI access
kubectl port-forward -n openbao svc/openbao 8200:8200 &
# Configure CLI (use the root token from Step 2)
export BAO_ADDR="http://127.0.0.1:8200"
export BAO_TOKEN="$OPENBAO_ROOT_TOKEN"
Alternatively, you can run bao commands directly inside the OpenBao pod:
kubectl exec -n openbao openbao-0 -- sh -c "BAO_TOKEN=<token> bao <command>"
Note: The remaining steps in this guide use the local CLI. If using the in-pod approach, prefix each
baocommand with thekubectl execpattern above.
Step 4: Enable KV v2 Secrets Engine#
bao secrets enable -path=secret kv-v2
Verify:
bao secrets list
You should see secret/ listed as kv version 2.
Step 5: Write Test Secrets#
bao kv put secret/myapp username='admin-user' password='super-secret-password'
Verify:
bao kv get secret/myapp
Step 6: Create OpenBao Read Policy#
bao policy write myapp-read - <<EOF
path "secret/data/myapp" {
capabilities = ["read"]
}
path "secret/metadata/myapp" {
capabilities = ["read"]
}
EOF
Step 7: Enable Kubernetes Auth#
# Enable Kubernetes auth method
bao auth enable kubernetes
# Configure Kubernetes auth
bao write auth/kubernetes/config \
kubernetes_host='https://kubernetes.default.svc.cluster.local'
Step 8: Enable AppRole Auth (Optional)#
Only required for the BSO AppRole pattern.
bao auth enable approle
How Reloader Works#
- Secret provider updates K8s Secret - ESO/BSO/CSI syncs secrets from OpenBao
- Reloader detects change - Watches for Secret changes via Kubernetes API
- Pod restart triggered - Rolling restart of pods referencing the changed Secret
Reloader Annotations#
On Deployment (for K8s Secret-based patterns: ESO, BSO, CSI with secretObjects):
metadata:
annotations:
reloader.stakater.com/search: "true"
On Secret (must be annotation, not label):
metadata:
annotations:
reloader.stakater.com/match: "true"
On Deployment (for CSI file-based pattern only):
metadata:
annotations:
secretproviderclass.reloader.stakater.com/reload: "<secretproviderclass-name>"
Pattern-Specific Guides#
- External Secrets Operator Pattern - Token or Kubernetes auth
- OpenBao Secrets Operator Pattern - Kubernetes auth or AppRole
- CSI Driver Pattern - Kubernetes auth (syncs to K8s Secret)
- CSI Driver File-Based Pattern - Kubernetes auth (file-only, no K8s Secret)