Skip to main content
Version: 0.1.0-rc.5

Prerequisites

Requirements
  • Kubernetes: v1.33+ (see Compatibility)
  • kubectl: Installed and configured
  • Permissions: Cluster-admin access for CRDs, RBAC, and ValidatingAdmissionPolicies
  • Helm (optional): v3.12+ for Helm-based installation
Deployment Modes

The operator supports two deployment modes:

  • Multi-Tenant (default): Platform teams providing OpenBao-as-a-Service
  • Single-Tenant: Individual teams deploying OpenBao for their application

See Single-Tenant Mode for single-tenant deployments.

Install Profiles

Use this table to choose the supported install path before you start changing values or overlays. For most environments, the default answer is Helm plus multi-tenant mode unless your namespace ownership model says otherwise.

Decision matrix

Supported installation paths

Supported installation paths.
IntentRecommended pathChange these settingsVerify these outputs
Dedicated team namespaceHelm, tenancy.mode=singletenancy.targetNamespace, optional release namespaceonly the controller pod runs; WATCH_NAMESPACE matches the target namespace
Dedicated team namespace with custom Helm identityHelm, tenancy.mode=single plus custom release name or fullnameOverriderelease name or fullnameOverride, tenancy.targetNamespace, optional release namespacerendered controller ServiceAccount name, single-tenant RoleBinding subject, admission-policy identity variables, JWT audience
Raw multi-tenant install with default identityconfig/defaultoperator namespace only if you want to fork the default baserendered namespace, controller and provisioner ServiceAccount names, admission policies
Raw multi-tenant install with custom identityconfig/overlays/custom-identitynamespace, optional namePrefixrendered ServiceAccount names, RoleBinding subjects, admission-policy identity variables, JWT audience
Raw single-tenant installconfig/overlays/single-tenantoperator namespace in the overlay, target namespace in target_namespace_config.yamlrendered operator namespace, WATCH_NAMESPACE, single-tenant RoleBinding subject
Raw single-tenant install with custom identityconfig/overlays/single-tenant-custom-identitynamespace, optional namePrefix, target namespace in target_namespace_config.yamlrendered operator namespace, controller ServiceAccount name, WATCH_NAMESPACE, single-tenant RoleBinding subject, admission-policy identity variables
Single-Tenant Customization Boundary

Use config/overlays/single-tenant when you only need a custom operator namespace or target namespace. Use config/overlays/single-tenant-custom-identity when you also need a custom operator identity, such as an extra namePrefix.

Default recommendation

Start with Helm, keep the default multi-tenant mode, pin the image tag for production, and leave admission policies enabled. Deviate from that path only when raw-manifest control or single-tenant namespace ownership is an explicit requirement.

Installation

Install the operator using the official Helm chart:

Rendered operator namespace

The examples below use the default release namespace openbao-operator-system. If you install the chart into another namespace, replace it consistently in the commands and later verification steps.

Apply

Install the Helm chart

bash

helm install openbao-operator oci://ghcr.io/dc-tec/charts/openbao-operator \
--namespace openbao-operator-system \
--create-namespace

Common Configuration

Configure

Pin a release and right-size the controller

bash

helm install openbao-operator oci://ghcr.io/dc-tec/charts/openbao-operator \
--namespace openbao-operator-system \
--create-namespace \
--set image.tag=1.0.0 \
--set controller.replicas=2 \
--set controller.resources.limits.memory=512Mi
  1. Pin to a specific version for production deployments.
  2. Run multiple replicas for high availability.
  3. Adjust resource limits based on cluster size.

Single-Tenant With Custom Helm Identity

Helm already supports the equivalent of the raw-manifest custom-identity overlays through the release name and fullnameOverride.

Configure

Install in single-tenant mode with a custom identity

bash

helm install team-bao oci://ghcr.io/dc-tec/charts/openbao-operator \
--namespace platform-operators \
--create-namespace \
--set tenancy.mode=single \
--set tenancy.targetNamespace=openbao \
--set fullnameOverride=team-bao-operator

Confirm with helm template or helm get manifest that:

  1. the controller ServiceAccount name matches the rendered Helm fullname
  2. the single-tenant RoleBinding subject points at that rendered controller ServiceAccount
  3. admission-policy variables reference the same rendered operator namespace and controller ServiceAccount name
  4. OPENBAO_JWT_AUDIENCE on the controller still matches the projected openbao-token audience
note

The chart does not expose per-component custom ServiceAccount names. Use the release name or fullnameOverride to customize the operator identity while keeping the rendered RBAC and admission-policy references aligned.

Artifact Hub

Discover package metadata and install snippets on Artifact Hub:

note

Artifact Hub indexing can lag shortly after a release is published.

Full Values Reference

ParameterDescriptionDefault
image.repositoryOperator image repositoryghcr.io/dc-tec/openbao-operator
image.tagImage tag (defaults to appVersion)""
image.pullPolicyImage pull policyIfNotPresent
imagePullSecretsRegistry credentials[]
platformTarget platform (auto, kubernetes, openshift)auto
tenancy.modemulti or singlemulti
tenancy.targetNamespaceTarget namespace (single-tenant only)""
controller.replicasController replica count1
controller.resourcesController resource requests/limitsSee values.yaml
provisioner.replicasProvisioner replica count1
provisioner.resourcesProvisioner resource requests/limitsSee values.yaml
admissionPolicies.enabledEnable ValidatingAdmissionPoliciestrue
metrics.enabledEnable metrics endpointstrue

Full values.yaml

Air-Gapped Environments

To use private registries for the operator and its sidecars (init, backup, upgrade), see the Air-Gapped / Private Registries guide.

Render Verification

Use this checklist for raw-manifest installs before you apply the manifests.

Multi-Tenant With Custom Identity

Render the overlay:

Inspect

Render the custom-identity overlay

bash

kubectl kustomize config/overlays/custom-identity

Confirm:

  1. the rendered operator namespace is the namespace you expect
  2. the controller and provisioner ServiceAccount names match your intended install identity
  3. RoleBinding and ClusterRoleBinding subjects point at those rendered ServiceAccounts
  4. admission-policy variables reference the same rendered namespace and ServiceAccount names
  5. OPENBAO_JWT_AUDIENCE on the controller matches the projected openbao-token audience

See Operator Authentication for the OpenBao-side JWT binding checks.

Single-Tenant Raw Manifests

Render the overlay:

Inspect

Render the single-tenant overlay

bash

kubectl kustomize config/overlays/single-tenant

Confirm:

  1. the rendered operator namespace matches config/overlays/single-tenant/kustomization.yaml
  2. WATCH_NAMESPACE on the controller matches config/overlays/single-tenant/target_namespace_config.yaml
  3. the single-tenant RoleBinding namespace matches the same target namespace
  4. the controller ServiceAccount subject in that RoleBinding points at the rendered operator namespace

If you customize the single-tenant overlay beyond those supported fields, treat the render output as the source of truth.

Single-Tenant With Custom Identity

Render the overlay:

Inspect

Render the single-tenant custom-identity overlay

bash

kubectl kustomize config/overlays/single-tenant-custom-identity

Confirm:

  1. the rendered operator namespace matches config/overlays/single-tenant-custom-identity/kustomization.yaml
  2. the rendered controller ServiceAccount name matches the same overlay after any namePrefix
  3. WATCH_NAMESPACE on the controller matches config/overlays/single-tenant-custom-identity/target_namespace_config.yaml
  4. the single-tenant RoleBinding subject points at the rendered controller ServiceAccount
  5. controller admission-policy variables reference the same rendered namespace and ServiceAccount name

Verify Installation

Check that the operator pods are running:

Verify

Check that the operator pods are running

bash

kubectl get pods -n <operator-namespace>

Expected output (multi-tenant mode):

Output

Expected output in multi-tenant mode

text

NAME                                              READY   STATUS    RESTARTS   AGE
<controller-pod> 1/1 Running 0 1m
<provisioner-pod> 1/1 Running 0 1m
Do not move on until the operator namespace looks exactly how you expect.

A good install checkpoint is more than pods in Running:

  • the controller and provisioner pods match the tenancy mode you chose
  • the rendered namespace and ServiceAccount names match your install plan
  • admission policies are installed when they are supposed to be
  • in the default multi-tenant path, you know which namespace will receive the first OpenBaoTenant
  • your next step is tenant onboarding or cluster creation, not more install debugging

Upgrading

Helm Upgrades

CRD Updates

Helm does not automatically upgrade CRDs. For releases with CRD changes:

  1. Apply CRDs from the release assets first:
    kubectl apply -f https://github.com/dc-tec/openbao-operator/releases/download/X.Y.Z/crds.yaml
  2. Then upgrade the Helm release:
    helm upgrade openbao-operator oci://ghcr.io/dc-tec/charts/openbao-operator \
    --namespace openbao-operator-system

YAML Manifest Upgrades

kubectl apply -f https://github.com/dc-tec/openbao-operator/releases/download/X.Y.Z/install.yaml

For custom raw-manifest installs, use your rendered namespace, ServiceAccount names, and policy names rather than assuming the repository defaults.

Uninstallation

helm uninstall openbao-operator --namespace openbao-operator-system
CRDs Retained

Helm does not delete CRDs by design. To fully remove:

kubectl delete crd openbaoclusters.openbao.org openbaorestores.openbao.org openbaotenants.openbao.org

Next Steps

Next actions

Prerelease documentation

This version tracks a prerelease build. Features and behavior may change before the next stable release.

Was this page helpful?

Use Needs work to open a structured GitHub issue for this page. The Yes button only acknowledges the signal locally.