Get started
OpenBao provides centralized, well-audited privileged access and secret management for mission-critical data whether you deploy systems on-premises, in the cloud, or in a hybrid environment. The project originated as a community-driven fork of HashiCorp Vault and is currently developed under the stewardship of the Linux Foundation.
Before exploring the chart characteristics, let’s start by deploying the default configuration:
helm install <release-name> oci://dp.apps.rancher.io/charts/openbao \
--set global.imagePullSecrets={application-collection}Please check our authentication guide if you need to configure Application Collection OCI credentials in your Kubernetes cluster.
Chart overview
The OpenBao Helm chart distributed in Application Collection is based on the official OpenBao Helm chart and adapted to include our best practices. As such, any chart-related documentation provided by upstream will work out of the box with our chart. In addition to the upstream chart repository, you can check the official OpenBao documentation .
By default, the chart will deploy a single OpenBao server in standalone mode
with a 10Gi volume for data storage and an OpenBao Agent Injector admission webhook controller.
Server modes
The OpenBao server can be deployed in 3 modes:
- Development: this mode does not require initialization or unsealing setup and it is intended for experimentation only. Data is not
persisted. The Helm parameters that control this mode are
server.dev.*. Read more on this in the official documentation . - Standalone: this is the default mode. It deploys a single replica and persists the data in a volume by using the “file” backend. OpenBao
needs to be initialized after Helm installation. The Helm parameters that control this mode are
server.standalone.*. - High-Availability: in HA mode, multiple OpenBao servers are deployed. By default, Consul is configured as storage backend but others can
be configured manually, such as the integrated Raft storage. The Helm parameters that control this mode are
server.ha.*. More information can be found in the official documentation .
Chart configuration
To view the supported configuration options and documentation, run:
helm show values oci://dp.apps.rancher.io/charts/openbaoRefer to the OpenBao Helm chart documentation to learn more about configuring the Helm chart.
Development mode
The simplest way to start experimenting with the OpenBao application is activating the development mode when installing the Helm chart. As an example, you would provide the Helm chart values below to activate this mode. A root token can be specified from the Helm chart values for ease of use:
server:
dev:
enabled: true
devRootToken: adminhelm install <release-name> oci://dp.apps.rancher.io/charts/openbao \
--set global.imagePullSecrets={application-collection} \
--values dev.yamlA single replica StatefulSet is deployed without requiring any further initialization steps:
$ kubectl get statefulset/<release-name>
NAME READY AGE
<release-name> 1/1 21sTo confirm that the provided root token is being applied, run the command below:
$ kubectl exec statefulset/<release-name> -- bao print token
adminSecrets can be created and retrieved via CLI and API:
$ kubectl exec statefulset/<release-name> -- bao kv put -mount=secret test foo=bar
== Secret Path ==
secret/data/test
...$ kubectl port-forward svc/<release-name> 8200
$ curl --header "X-Vault-Token: admin" http://localhost:8200/v1/secret/data/test
{"request_id":"160b676c-a566-f0c9-b344-2258e7d80355","lease_id":"","renewable":false,"lease_duration":0,"data":{"data":{"foo":"bar"},"metadata":{"created_time":"2026-09-17T09:43:46.104771593Z","custom_metadata":null,"deletion_time":"","destroyed":false,"version":1}},"wrap_info":null,"warnings":null,"auth":null}OpenBao keeps the X-Vault-Token header and the bao CLI’s VAULT_* environment variables working for backward compatibility with existing
Vault tooling, alongside their BAO_-prefixed equivalents.
Standalone mode
If you install OpenBao using the default standalone setup, you’ll need to complete a few extra steps to finish setting it up:
helm install <release-name> oci://dp.apps.rancher.io/charts/openbao \
--set global.imagePullSecrets={application-collection}The logs show that the server is pending to be initialized and unsealed:
$ kubectl logs statefulset/<release-name>
...
2026-09-17T09:44:48.119Z [INFO] core: security barrier not initialized
2026-09-17T09:44:48.119Z [INFO] core: seal configuration missing, not initialized
...Run operator init and operator unseal
to finish the setup:
$ kubectl exec statefulset/<release-name> -- bao operator init -key-shares=1 -key-threshold=1
Unseal Key 1: <generated_unseal_key>
...Copy the unseal key (<generated_unseal_key>) and run the operator unseal command with it. The command shows that OpenBao is now
initialized and unsealed:
$ kubectl exec statefulset/<release-name> -- bao operator unseal <generated_unseal_key>
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
...The installation is now ready:
$ kubectl get statefulset/<release-name>
NAME READY AGE
<release-name> 1/1 2m32sHigh-Availability mode
The High-Availability (HA) mode deploys multiple OpenBao server replicas. To illustrate it with an example, the Raft storage backend will be used. You can configure this mode and storage backend via Helm chart parameters:
server:
# Uncomment this line if your cluster has a single node: this schedules all pods in the same node
# affinity: ""
ha:
enabled: true
replicas: 3
raft:
enabled: truehelm install <release-name> oci://dp.apps.rancher.io/charts/openbao \
--set global.imagePullSecrets={application-collection} \
--values ha.yamlInitialize the first replica and copy the credentials:
$ kubectl exec <release-name>-0 -- bao operator init -key-shares=1 -key-threshold=1
Unseal Key 1: <generated_unseal_key>
Initial Root Token: <some_initial_root_token>
...Run these commands to finish the initialization of the OpenBao cluster:
$ kubectl exec <release-name>-0 -- bao operator unseal <generated_unseal_key>
$ kubectl exec <release-name>-1 -- bao operator raft join http://<release-name>-0.<release-name>-internal:8200
Key Value
--- -----
Joined true
$ kubectl exec <release-name>-1 -- bao operator unseal <generated_unseal_key>
$ kubectl exec <release-name>-2 -- bao operator raft join http://<release-name>-0.<release-name>-internal:8200
Key Value
--- -----
Joined true
$ kubectl exec <release-name>-2 -- bao operator unseal <generated_unseal_key>Now all the OpenBao cluster replicas should be ready:
$ kubectl exec statefulset/<release-name> -- bao login <some_initial_root_token>
$ kubectl exec statefulset/<release-name> -- bao operator raft list-peers
Node Address State Voter
---- ------- ----- -----
db4cc75a-99da-9e84-2972-e8f1a61ec7b2 <release-name>-0.<release-name>-internal:8201 leader true
82c35180-0b56-7e2c-06a0-24d19494ebfe <release-name>-1.<release-name>-internal:8201 follower true
ccb174a5-5e39-4c97-3208-67639431cf0a <release-name>-2.<release-name>-internal:8201 follower true
$ kubectl exec <release-name>-0 -- bao status
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
...
Storage Type raft
...
HA Enabled true
HA Cluster https://<release-name>-0.<release-name>-internal:8201
HA Mode active
...
$ kubectl exec <release-name>-1 -- bao status
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
...
Storage Type raft
...
HA Enabled true
HA Cluster https://<release-name>-0.<release-name>-internal:8201
HA Mode standby
$ kubectl exec <release-name>-2 -- bao status
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
...
Storage Type raft
...
HA Enabled true
HA Cluster https://<release-name>-0.<release-name>-internal:8201
HA Mode standby
$ kubectl get statefulset/<release-name>
NAME READY AGE
<release-name> 3/3 4m56sAccess the UI
The OpenBao Helm chart can expose the web UI as an independent service that allows you to easily manage its configurations. To create this UI service simply enable it with the Helm chart parameter below:
# OpenBao UI
ui:
# True if you want to create a Service entry for the OpenBao UI.
enabled: truehelm install <release-name> oci://dp.apps.rancher.io/charts/openbao \
--set global.imagePullSecrets={application-collection} \
--values ui.yamlOpenBao Agent Injector
The OpenBao Agent Injector is a Kubernetes admission webhook controller
that intercepts pod events and updates their specification based on certain annotations. Thanks to this controller, OpenBao secrets can be
injected into pods by mounting them as volumes. This functionality can be controlled by Helm chart parameters (injector.*). Read more on this
feature in the official documentation . As an example, you would provide the Helm chart values below
to make sure this mode is activated. For simplicity, the development mode is used:
injector:
enabled: truehelm install <release-name> oci://dp.apps.rancher.io/charts/openbao \
--set global.imagePullSecrets={application-collection} \
--values injector.yaml \
--set server.dev.enabled=trueOnce the Helm installation finishes, create a new OpenBao secret:
kubectl exec statefulset/<release-name> -- bao kv put -mount=secret test-injector foo=barThen, configure Kubernetes authentication and OpenBao policies to interact with that secret:
kubectl exec statefulset/<release-name> -- bao auth enable kubernetes
kubectl exec statefulset/<release-name> -- bash -c 'bao write auth/kubernetes/config kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443"'
kubectl exec -i statefulset/<release-name> -- bao policy write test-injector - <<EOF
path "secret/data/test-injector" {
capabilities = ["read"]
}
EOF
kubectl exec statefulset/<release-name> -- bao write auth/kubernetes/role/test-injector bound_service_account_names=test-injector bound_service_account_namespaces=default policies=test-injector
kubectl create serviceaccount test-injectorTo finish, confirm that the secret is automatically mounted into the pods with proper metadata annotations. The injector still relies on the
legacy vault.hashicorp.com/* annotation prefix for backward compatibility with existing Vault workflows:
kubectl run test-injector --image dp.apps.rancher.io/containers/nginx:1.31 \
--overrides='{"spec": {"serviceAccount": "test-injector", "imagePullSecrets":[{"name": "application-collection"}]}}' \
--annotations=vault.hashicorp.com/agent-inject=true \
--annotations=vault.hashicorp.com/role=test-injector \
--annotations=vault.hashicorp.com/agent-inject-secret-test.txt=secret/data/test-injector$ kubectl exec test-injector -c test-injector -- cat /vault/secrets/test.txt
data: map[foo:bar]
...Operations
Upgrade the chart
In general, an in-place upgrade of your OpenBao installation can be performed using the built-in Helm upgrade workflow:
helm upgrade <release-name> oci://dp.apps.rancher.io/charts/openbaoThe pods will be upgraded by following the update strategy defined in the values.yaml file.
Be aware that changes from version to version may include breaking changes in OpenBao itself or in the Helm chart templates. In other cases, the upgrade process may require additional steps to be performed. Always check the release notes and the upgrade guides before proceeding with an upgrade.
Uninstall the chart
Removing an installed OpenBao Helm chart release is simple:
helm uninstall <release-name>The OpenBao nodes are deployed as StatefulSets , hence using Volume Claim Templates to store your most precious resource in a database installation: your data. These PVCs are not directly controlled by Helm and they are not removed when uninstalling the related chart.
When you are ready to remove the PVCs and your data, you will need to explicitly delete them:
kubectl delete pvc --selector app.kubernetes.io/instance=<release-name>Remember to remove any other resources you deployed during this guide:
kubectl delete pod test-injector
kubectl delete serviceaccount test-injector