Skip to content

On-Prem OpenBao Helm Values

The cloudtaser-openbao chart deploys OpenBao in HA mode and bootstraps it for CloudTaser using cloudtaser-cli secretstore init.

This chart automates the deployment of the EU-hosted secret store that forms the root of trust for CloudTaser data sovereignty. It deploys a 3-node HA Raft cluster with audit logging, and automatically configures Kubernetes authentication so that pods can retrieve secrets without manual setup.


Overview

Chart: cloudtaser-openbao Source: cloudtaser-onprem/charts/cloudtaser-openbao/

The chart wraps the official OpenBao Helm chart as a dependency and adds a post-install bootstrap Job. The bootstrap Job runs cloudtaser-cli secretstore init, which handles the full initialization sequence:

  1. Wait for OpenBao pod-0 to be reachable
  2. Initialize with Shamir secret sharing
  3. Unseal all HA replicas
  4. Join followers to the Raft cluster
  5. Enable audit logging, KV v2, and Kubernetes auth
  6. Create CloudTaser policy and role
  7. Store unseal keys and root token in a Kubernetes Secret

Installation

helm repo add openbao https://openbao.github.io/openbao-helm
helm dependency build charts/cloudtaser-openbao/
helm install cloudtaser-openbao charts/cloudtaser-openbao/ \
  --namespace cloudtaser-vault \
  --create-namespace

Values Reference

Global

Value Type Default Description
namespace string cloudtaser-vault Namespace for the OpenBao deployment

openbao.*

These values are passed through to the upstream OpenBao Helm chart.

Value Type Default Description
openbao.server.ha.enabled bool true Enable HA mode
openbao.server.ha.replicas int 3 Number of HA replicas
openbao.server.ha.raft.enabled bool true Use Raft for HA storage backend
openbao.server.auditStorage.enabled bool true Enable persistent storage for audit logs
openbao.server.auditStorage.size string 10Gi Audit storage volume size
openbao.server.dataStorage.enabled bool true Enable persistent storage for data
openbao.server.dataStorage.size string 10Gi Data storage volume size
openbao.server.resources.requests.cpu string 250m CPU request
openbao.server.resources.requests.memory string 256Mi Memory request
openbao.server.resources.limits.cpu string 1 CPU limit
openbao.server.resources.limits.memory string 512Mi Memory limit
openbao.injector.enabled bool false Disable the OpenBao injector (CloudTaser uses its own wrapper injection)
openbao:
  server:
    ha:
      enabled: true
      replicas: 3
      raft:
        enabled: true
    auditStorage:
      enabled: true
      size: 10Gi
    dataStorage:
      enabled: true
      size: 10Gi
    resources:
      requests:
        cpu: 250m
        memory: 256Mi
      limits:
        cpu: "1"
        memory: 512Mi
  injector:
    enabled: false

OpenBao injector

The OpenBao injector is explicitly disabled (injector.enabled: false). CloudTaser uses its own mutating webhook for sidecar injection via the cloudtaser-operator. Running both injectors would cause conflicts.

bootstrap.*

Configuration for the post-install bootstrap Job that runs cloudtaser-cli secretstore init.

Value Type Default Description
bootstrap.enabled bool true Enable the bootstrap Job
bootstrap.image.repository string ghcr.io/cloudtaser/cloudtaser-cli Bootstrap container image
bootstrap.image.tag string latest Bootstrap image tag
bootstrap.image.pullPolicy string IfNotPresent Image pull policy

Shamir Secret Sharing

Value Type Default Description
bootstrap.shamir.shares int 5 Number of Shamir key shares generated during initialization
bootstrap.shamir.threshold int 3 Minimum number of shares required to unseal

Shamir parameters

The default 5/3 split means 5 unseal keys are generated and any 3 are needed to unseal. For production, distribute shares to different key holders. The bootstrap Job uses all shares automatically during initial setup.

Secret Engine

Value Type Default Description
bootstrap.kv.path string secret KV v2 secret engine mount path

Kubernetes Auth

Value Type Default Description
bootstrap.auth.path string kubernetes Kubernetes auth method mount path

Policy

Value Type Default Description
bootstrap.policy.name string cloudtaser Policy name for CloudTaser read access
bootstrap.policy.kvReadPaths list ["secret/data/*", "secret/metadata/*"] KV paths the policy grants read access to

Role

Value Type Default Description
bootstrap.role.name string cloudtaser Kubernetes auth role name
bootstrap.role.boundServiceAccountNames string * Service accounts allowed to authenticate. * allows any service account
bootstrap.role.boundServiceAccountNamespaces string * Namespaces allowed to authenticate. * allows any namespace
bootstrap.role.ttl string 1h Token TTL for authenticated pods

Output

Value Type Default Description
bootstrap.outputSecret.name string cloudtaser-openbao-init Kubernetes Secret name where unseal keys and root token are stored

Full Default Values

namespace: cloudtaser-vault

openbao:
  server:
    ha:
      enabled: true
      replicas: 3
      raft:
        enabled: true
    auditStorage:
      enabled: true
      size: 10Gi
    dataStorage:
      enabled: true
      size: 10Gi
    resources:
      requests:
        cpu: 250m
        memory: 256Mi
      limits:
        cpu: "1"
        memory: 512Mi
  injector:
    enabled: false

bootstrap:
  enabled: true
  image:
    repository: ghcr.io/cloudtaser/cloudtaser-cli
    tag: "latest"
    pullPolicy: IfNotPresent
  shamir:
    shares: 5
    threshold: 3
  kv:
    path: "secret"
  auth:
    path: "kubernetes"
  policy:
    name: "cloudtaser"
    kvReadPaths:
      - "secret/data/*"
      - "secret/metadata/*"
  role:
    name: "cloudtaser"
    boundServiceAccountNames: "*"
    boundServiceAccountNamespaces: "*"
    ttl: "1h"
  outputSecret:
    name: "cloudtaser-openbao-init"

Bootstrap Job Details

The bootstrap Job is a Helm post-install hook that runs after the OpenBao StatefulSet is created. It uses the cloudtaser-cli image and executes cloudtaser-cli secretstore init.

The Job's environment variables are set from the Helm values above:

Environment Variable Source Value
OPENBAO_ADDR Computed from chart fullname and namespace
OPENBAO_NAMESPACE namespace
OPENBAO_RELEASE_NAME Computed from chart fullname
BOOTSTRAP_SHAMIR_SHARES bootstrap.shamir.shares
BOOTSTRAP_SHAMIR_THRESHOLD bootstrap.shamir.threshold
BOOTSTRAP_KV_PATH bootstrap.kv.path
BOOTSTRAP_AUTH_PATH bootstrap.auth.path
BOOTSTRAP_POLICY_NAME bootstrap.policy.name
BOOTSTRAP_ROLE_NAME bootstrap.role.name
BOOTSTRAP_OUTPUT_SECRET bootstrap.outputSecret.name
BOOTSTRAP_ROLE_BOUND_SA_NAMES bootstrap.role.boundServiceAccountNames
BOOTSTRAP_ROLE_BOUND_SA_NAMESPACES bootstrap.role.boundServiceAccountNamespaces
BOOTSTRAP_ROLE_TTL bootstrap.role.ttl

The Job has a backoffLimit of 5 and an activeDeadlineSeconds of 600 (10 minutes).

Retrieving Unseal Keys

After installation, the unseal keys and root token are stored in the Kubernetes Secret specified by bootstrap.outputSecret.name:

kubectl get secret cloudtaser-openbao-init \
  -n cloudtaser-vault \
  -o jsonpath='{.data}' | jq 'to_entries[] | {key: .key, value: (.value | @base64d)}'

Secure the output secret

The output secret contains the root token and all unseal keys. In production, retrieve these values, distribute unseal keys to key holders, revoke the root token, and delete the Kubernetes Secret.

Example: Restricted Access Configuration

values-restricted.yaml
bootstrap:
  shamir:
    shares: 7
    threshold: 4
  role:
    boundServiceAccountNames: "myapp-sa,worker-sa"
    boundServiceAccountNamespaces: "production,staging"
    ttl: "30m"
  policy:
    kvReadPaths:
      - "secret/data/myapp/*"
      - "secret/metadata/myapp/*"