Unseal trust and credential contracts
The unseal path defines where the root of trust lives, how credentials reach the Pods, and which Secret keys or mounted files each mode requires. Use this page to map a chosen unseal mode to the exact operator contract.
For production-oriented clusters, use an external trust source such as cloud KMS, transit, KMIP, OCI KMS, or PKCS#11. Reserve static unseal for development and controlled exceptions because it keeps decryption material inside Kubernetes.
Decision matrix
Choose the unseal path deliberately
| Path | Use it when | Main operator expectation |
|---|---|---|
| Static | You need the lightest development or evaluation path. | The operator manages a per-cluster Secret unless you deliberately override that path. |
| Transit | You already run a central OpenBao trust root or another intentional upstream unseal service. | The credentials Secret must carry the transit token and any referenced TLS files. |
| Cloud KMS | You want the root of trust outside Kubernetes and your platform already provides a KMS path. | Prefer workload identity or ambient credentials; only use Secrets when that identity path is unavailable or intentionally overridden. |
| KMIP / PKCS#11 | You need HSM-backed or enterprise key-management integration. | The Secret contract is mostly file- or PIN-oriented and must match the rendered configuration exactly. |
General rules
spec.unseal.credentialsSecretRefmust reference a Secret in the same namespace as theOpenBaoCluster.- Any unseal field that points to a mounted credential file must use a path under
/etc/bao/seal-creds. - The Secret key name must match the filename used in the mounted path.
- When you use private ACME trust rooted under
/etc/bao/seal-creds, includepki-ca.crtin the same Secret so probes and day-2 operations can trust the ACME issuer too.
How mounted credential paths map 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"
gcpCloudKMS:
credentials: "/etc/bao/seal-creds/credentials.json"
kmip:
clientCert: "/etc/bao/seal-creds/kmip-client.crt"
clientKey: "/etc/bao/seal-creds/kmip-client.key"
caCert: "/etc/bao/seal-creds/kmip-ca.crt"
In this example, the Secret named unseal-creds must contain keys named ca.crt, client.crt, client.key, credentials.json, kmip-client.crt, kmip-client.key, and kmip-ca.crt.
Provider credential contracts
Reference table
Secret requirements by provider
| Provider | When a Secret is needed | Required keys or file contract | Notes |
|---|---|---|---|
| Static | Usually not needed because the operator generates the Secret automatically. | Generated Secret <cluster-name>-unseal-key with key key. | Use this only for development or controlled exceptions. If you replace it manually, keep the same key name. |
| Transit | Needed whenever you do not rely only on an inline token and Secret-backed files are referenced. | token, plus any mounted files referenced by tlsCACert, tlsClientCert, and tlsClientKey. | If client cert auth is used, the certificate and key must both be present and form a valid key pair. |
| AWS KMS | Required if you are not using IRSA, ambient credentials, or another default AWS credential chain. | AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. | Prefer workload identity when that path is available and intended. |
| GCP Cloud KMS | Required if spec.unseal.gcpCloudKMS.credentials points at a mounted file instead of using Workload Identity or ADC. | A Secret key matching the configured file name, usually credentials.json, containing valid JSON credentials. | The path must live under /etc/bao/seal-creds. |
| Azure Key Vault | Required if you are not using Managed Identity or Azure Workload Identity. | AZURE_TENANT_ID, AZURE_CLIENT_ID, and AZURE_CLIENT_SECRET. | Managed identity is the preferred Hardened path when your platform supports it. |
| OCI KMS | Required if spec.unseal.ocikms.authTypeAPIKey=true. | config, plus the Secret key referenced by key_file inside the OCI SDK config. | The OCI config must define user, fingerprint, tenancy, region, and key_file in profile [DEFAULT], and key_file must point under /etc/bao/seal-creds. |
| KMIP | Needed whenever client cert, key, or CA files are sourced from mounted credentials. | Secret keys matching the filenames referenced by clientCert, clientKey, and optional caCert under /etc/bao/seal-creds. | The client certificate and key must form a valid pair; the CA bundle must be valid PEM when set. The KMIP key must already exist and be usable for encrypt/decrypt before the cluster starts. |
| PKCS#11 | Needed when spec.unseal.pkcs11.pin is omitted or PKCS#11 runtime env/config files are sourced from Secret data. | BAO_HSM_PIN, plus every key referenced by spec.unseal.pkcs11.runtime.env[*].secretKey and spec.unseal.pkcs11.runtime.fileEnv[*].secretKey. | The operator also requires either slot or tokenLabel, but not both. The OpenBao image must include HSM support and the configured vendor PKCS#11 module. |
KMIP provider contract
KMIP is a network-backed seal path. The operator renders the OpenBao KMIP seal stanza, projects mTLS files from credentialsSecretRef, and validates mounted certificate material before the workload starts. It does not create KMIP key material or configure the KMIP server.
For production clusters, prepare the KMIP side first:
- Create or register the wrapping key in the KMIP service.
- Activate the key and allow encrypt/decrypt operations for the OpenBao client identity.
- Issue a client certificate with
clientAuthextended key usage. - Issue or trust a server certificate whose DNS name matches
spec.unseal.kmip.serverName. - Set
tls12Cipherswhen the KMIP appliance requires a constrained TLS 1.2 cipher suite.
KMIP unseal with Secret-backed mTLS files
apiVersion: openbao.org/v1alpha1
kind: OpenBaoCluster
metadata:
name: bao-kmip
namespace: openbao
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
tls12Ciphers: TLS_RSA_WITH_AES_128_CBC_SHA256
The Secret kmip-client must contain client.crt, client.key, and ca.crt. The operator validates that the client certificate and key form a valid pair and that the CA bundle parses as PEM before OpenBao starts.
PKCS#11 runtime wiring
PKCS#11 deployments need two separate pieces before OpenBao can initialize or unseal: external key material in the HSM and a runtime that can load the vendor PKCS#11 module. OpenBao does not create PKCS#11 key material for you; create the key through the HSM vendor tooling before the cluster starts.
Use spec.unseal.pkcs11.runtime for vendor runtime settings that would otherwise require a custom entrypoint wrapper:
libraryPathsetsLD_LIBRARY_PATHfor vendor libraries that depend on sibling shared objects.envmaps environment variables to literal values stored incredentialsSecretRef.fileEnvmaps environment variables to mounted file paths under/etc/bao/seal-creds.
The operator manages the OpenBao seal-owned environment variables (BAO_SEAL_TYPE, BAO_HSM_LIB, BAO_HSM_PIN, and related BAO_HSM_* values) from spec.unseal.pkcs11; do not duplicate those names in runtime.env or runtime.fileEnv.
HSM deployment checklist
For PKCS#11-backed production clusters, validate the HSM integration outside the operator before creating the OpenBaoCluster:
- Use an OpenBao image with HSM support plus the vendor PKCS#11 module and dependent shared libraries.
- Pre-create the wrapping key in the HSM. OpenBao expects the key to exist and to allow the configured operation.
- Choose a mechanism that matches the HSM object type.
AES_GCMuses a secret key;RSA_PKCS_OAEPuses an RSA key pair and may requirersaOAEPHash. - Store the token PIN and vendor runtime material in
credentialsSecretRef; avoid puttingpindirectly in GitOps-managed manifests. - Use
runtime.libraryPathwhen the vendor module depends on sibling shared objects. - Use
runtime.envfor vendor settings that are literal values andruntime.fileEnvfor vendor settings that expect file paths. - Only keys referenced by
runtime.fileEnvare projected into the Pod as files. The PIN andruntime.envvalues remain Secret-backed environment variables and are not mounted under/etc/bao/seal-creds.
The wrapper fails fast when BAO_SEAL_TYPE=pkcs11 but the configured BAO_HSM_LIB is missing or points at a directory. Missing Secret keys are rejected during operator prerequisite validation before the workload reaches an opaque OpenBao startup failure.
PKCS#11 unseal with vendor runtime env
apiVersion: openbao.org/v1alpha1
kind: OpenBaoCluster
metadata:
name: bao-hsm
namespace: openbao
spec:
image: registry.example.com/openbao-hsm-vendor:2.5.3
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 pkcs11-runtime must include BAO_HSM_PIN, cryptoserver, and cs_pkcs11_R3.cfg. The operator projects only the fileEnv key cs_pkcs11_R3.cfg under /etc/bao/seal-creds, sets CS_PKCS11_R3_CFG=/etc/bao/seal-creds/cs_pkcs11_R3.cfg, and fails fast if /usr/local/lib/libpkcs11.so is not present in the container.
Static unseal details
Apply
Create or replace the static unseal Secret manually
kubectl -n <namespace> create secret generic <cluster-name>-unseal-key \
--from-literal=key='<UNSEAL_KEY>' \
--dry-run=client -o yaml | kubectl apply -f -
The operator-generated static Secret uses the name <cluster-name>-unseal-key and the data key key.
If spec.configuration.acmeCARoot points under /etc/bao/seal-creds, the Secret referenced by spec.unseal.credentialsSecretRef must also contain pki-ca.crt. This is how the operator and helper clients trust a private ACME issuer during probes and day-2 operations.
Continue baseline setup
You are reading the unreleased main docs. Use the version menu for the newest published release, or check the release notes for what is already out.
Was this page helpful?
Use Needs work to open a structured GitHub issue for this page. The Yes button only acknowledges the signal locally.