Configure unseal

Choose the unseal trust root and meet the exact workload-identity, Secret, file, or HSM contract.

Updated 9 August 2026 · 6 min read

On this page

Choose an unseal provider whose root of trust survives loss or compromise of the Kubernetes cluster. Hardened requires a non-static provider. Development can use the operator-managed static key.

Choose the trust root

TypeUse it whenPrimary credential path
awskms, gcpckms, azurekeyvaultThe cloud platform provides the external key servicePrefer workload identity; use a Secret only when needed
transitA separate OpenBao cluster owns the wrapping keyNamespace-local Secret for the token and optional mTLS files
ocikmsOCI KMS is the external trust sourcePrincipal identity or an OCI SDK config Secret
kmipAn enterprise key manager exposes KMIPSecret-mounted client certificate, key, and optional CA
kmsAn OpenBao 2.6+ KMS plugin owns the wrapping operationDeclared KMS plugin plus plugin-specific config and optional Secret-mounted files
pkcs11An HSM and vendor library are available in the OpenBao imageSecret-backed PIN and runtime environment or configuration files
staticThe cluster is disposable and uses DevelopmentOperator-generated immutable Kubernetes Secret

Supported types are static, awskms, gcpckms, azurekeyvault, transit, kmip, kms, ocikms, and pkcs11.

Apply the universal Secret contract

When spec.unseal.credentialsSecretRef is set:

  • the Secret must exist in the same namespace as the OpenBaoCluster;
  • the user applying the cluster must be authorized to get that Secret;
  • the name cannot match operator-managed system Secret suffixes such as -unseal-key, -root-token, -tls-ca, or -tls-server;
  • every referenced file under /etc/bao/seal-creds maps to a Secret key with the same filename;
  • missing, empty, invalid JSON, invalid PEM, or mismatched certificate material is rejected where the provider contract can validate it.

Use workload identity instead of long-lived cloud keys when the provider and platform support it. Inline cloud credentials remain API-supported, but they are stored in the OpenBaoCluster and therefore in etcd. Hardened rejects an inline transit token specifically.

reference

Map mounted paths to Secret keys

spec:
  unseal:
    credentialsSecretRef:
      name: unseal-creds
    transit:
      tlsCACert: /etc/bao/seal-creds/ca.crt
      tlsClientCert: /etc/bao/seal-creds/client.crt
      tlsClientKey: /etc/bao/seal-creds/client.key

This fragment requires unseal-creds keys named ca.crt, client.crt, and client.key.

Meet the provider credential contract

ProviderSecret keys or mounted-file requirements
AWS KMSAWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY; AWS_SESSION_TOKEN is optional. Omit the Secret for IRSA or the standard AWS credential chain.
GCP Cloud KMSA valid JSON key, normally credentials.json, when not using Workload Identity or Application Default Credentials.
Azure Key VaultAZURE_TENANT_ID, AZURE_CLIENT_ID, and AZURE_CLIENT_SECRET; optional environment and resource keys are also wired. Omit the Secret for managed identity or Azure Workload Identity.
Transittoken unless an inline token is used, plus files referenced by tlsCACert, tlsClientCert, and tlsClientKey. Client certificate and key must be set together.
OCI KMS API keyconfig with a [DEFAULT] profile and the key file named by key_file. Both files must be under /etc/bao/seal-creds.
KMIPFiles named by clientCert, clientKey, and optional caCert. The client certificate and key must match.
KMS pluginPlugin-specific keys for file paths referenced by spec.unseal.kms.config, normally under /etc/bao/seal-creds.
PKCS#11BAO_HSM_PIN when pin is omitted, plus every key referenced by runtime.env and runtime.fileEnv.

Configure a cloud KMS

Use a workload identity on the OpenBao ServiceAccount and omit the credential Secret. This AWS fragment shows the shape; GCP and Azure use their platform-specific ServiceAccount annotations or Pod labels.

configure

Use AWS KMS with workload identity

spec:
  serviceAccount:
    annotations:
      eks.amazonaws.com/role-arn: "arn:aws:iam::<account>:role/<openbao-kms-role>"
  unseal:
    type: awskms
    awskms:
      region: eu-west-1
      kmsKeyID: "arn:aws:kms:eu-west-1:<account>:key/<key-id>"

Grant only the KMS operations required by the provider. Confirm the workload identity can use the key before relying on it for a production bootstrap. Lifecycle Jobs have separate ServiceAccounts and do not inherit the main Pod’s cloud identity automatically.

Configure transit

Transit addresses must be absolute HTTPS URLs. The operator rejects userinfo, query strings, fragments, localhost, loopback, link-local, unspecified, scoped-IP, and ambiguous numeric-host forms.

configure

Use transit with Secret-backed credentials

spec:
  unseal:
    type: transit
    credentialsSecretRef:
      name: transit-unseal
    transit:
      address: "https://transit.example.com:8200"
      keyName: openbao-unseal
      mountPath: transit
      tlsCACert: /etc/bao/seal-creds/ca.crt

The Secret must contain token and ca.crt. Use an orphan or periodic token with only the transit encrypt and decrypt permissions. Set both tlsClientCert and tlsClientKey when using client-certificate authentication.

Configure a plugin-backed KMS seal

OpenBao 2.6.0 and later can use a plugin catalog entry with type: kms as the seal implementation. The unseal configuration must reference the declared plugin by name:

configure

Use a KMS seal plugin

spec:
  version: "2.6.1"
  configuration:
    plugin:
      autoDownload: true
      downloadBehavior: fail
  plugins:
    - type: kms
      name: corp-kms
      image: registry.example.com/openbao-kms-corp
      version: v0.1.0
      binaryName: openbao-kms-corp
      sha256sum: "<64-character-sha256>"
  unseal:
    type: kms
    credentialsSecretRef:
      name: corp-kms-runtime
    kms:
      pluginName: corp-kms
      config:
        endpoint: "https://kms-broker.example.com:8443"
        ca_file: "/etc/bao/seal-creds/ca.crt"

Config keys must be valid HCL identifiers and values are stored in the OpenBaoCluster; use paths to mounted Secret files for sensitive material. The operator verifies the plugin reference and renders string attributes, but the plugin owns the meaning of its config. With a command-based plugin, the binary must already exist in the OpenBao image before startup.

Configure KMIP

Create and activate the wrapping key in the KMIP system before the OpenBao cluster starts. Grant the client identity encrypt and decrypt operations. Issue a client certificate with clientAuth extended key usage and ensure the server certificate matches serverName.

configure

Use KMIP with mTLS files

spec:
  unseal:
    type: kmip
    credentialsSecretRef:
      name: kmip-client
    kmip:
      endpoint: kmip.example.com:5696
      kmsKeyID: "1"
      clientCert: /etc/bao/seal-creds/client.crt
      clientKey: /etc/bao/seal-creds/client.key
      caCert: /etc/bao/seal-creds/ca.crt
      serverName: kmip.example.com
      encryptAlg: AES_GCM

The Secret must contain client.crt, client.key, and ca.crt. Set tls12Ciphers only when the appliance requires a specific TLS 1.2 suite.

Configure PKCS#11

Prepare the HSM and runtime before creating the cluster:

  • build an OpenBao image with HSM support, the vendor PKCS#11 module, and dependent libraries;
  • create the wrapping key through vendor tooling;
  • choose slot or tokenLabel, but not both;
  • choose a mechanism compatible with the HSM object type;
  • store the PIN and vendor runtime material in credentialsSecretRef;
  • use runtime.libraryPath, runtime.env, and runtime.fileEnv instead of a custom wrapper script.
configure

Wire a PKCS#11 runtime

spec:
  image: registry.example.com/openbao-hsm-vendor:2.6.1
  unseal:
    type: pkcs11
    credentialsSecretRef:
      name: pkcs11-runtime
    pkcs11:
      lib: /usr/local/lib/libpkcs11.so
      tokenLabel: OpenBao
      keyLabel: bao-root-key-aes
      mechanism: AES_GCM
      runtime:
        libraryPath: /usr/local/lib
        env:
          - name: CRYPTOSERVER
            secretKey: cryptoserver
        fileEnv:
          - name: CS_PKCS11_R3_CFG
            secretKey: cs_pkcs11_R3.cfg

The Secret must contain BAO_HSM_PIN, cryptoserver, and cs_pkcs11_R3.cfg. Only fileEnv keys are mounted as files. The wrapper fails early when the library is missing or points to a directory.

Protect the static key

When unseal is omitted or set to static, the operator creates <cluster-name>-unseal-key with data key key. The Secret is immutable and carries owner proof for the OpenBaoCluster.

Do not pre-create, replace, patch, or delete that Secret. An unowned pre-existing Secret is rejected, and a replacement key cannot decrypt existing data. Back up and retain the operator-owned Secret according to the disposable cluster’s recovery requirements.

Account for private ACME trust

When spec.configuration.acmeCARoot points under /etc/bao/seal-creds, the unseal credentials Secret must also contain pki-ca.crt. The operator and helper clients use that fixed filename to trust the private ACME issuer during probes and day-2 operations.

Verify unseal readiness

verify

Inspect unseal and identity conditions

kubectl -n <namespace> get openbaocluster <name> \
  -o jsonpath='{range .status.conditions[*]}{.type}={.status}{"\t"}{.reason}{"\t"}{.message}{"\n"}{end}'

kubectl -n <namespace> get pods \
  -l openbao.org/cluster=<name>

Fix the first provider, Secret, identity, TLS, or network prerequisite reported by the operator. Do not bypass a failed unseal validation by weakening the profile.

Continue with storage.

Search the handbook

Try “install”, “threat model”, or “compatibility”.