Open Bao Vault using Builder Vault

PKCS#11 Auto-Unseal for OpenBao

This page describes how to configure OpenBao to auto-unseal using the
Builder Vault TSM PKCS#11 driver, so the root key is wrapped by a key held
in the TSM instead of requiring manual unseal operations with locally
held key shares.

OpenBao's PKCS#11 seal support is fully open source: it ships in the
bao-hsm release build, with no license file or separate entitlement
required.

Core Components Required

  • An OpenBao bao-hsm binary, downloaded from the
    openbao/openbao releases
    page (for example bao-hsm_2.4.0_Linux_amd64.tar.gz). PKCS#11 support is
    compiled in via cgo and is only present in the bao-hsm build — the plain
    bao binary does not have it.
  • The Builder Vault TSM PKCS#11 driver shared library (tsm-pkcs11.so on
    Linux, tsm-pkcs11.dylib on macOS/arm64).
  • A pkcs11.toml file describing the TSM nodes to connect to (PIN-protected).
  • opensc / pkcs11-tool, used once to pre-provision the unseal-wrapping
    key in the TSM before the first operator init (see Manual Key
    Provisioning
    below).

Configuration File: pkcs11.hcl

storage "file" {
  path = "/opt/openbao/bao-data"
}

listener "tcp" {
  address     = "0.0.0.0:8200"
  tls_disable = true
}

seal "pkcs11" {
  lib            = "/opt/sepior/tsm-pkcs11.so"
  slot           = 0
  pin            = "some password"
  key_label      = "bao-root-key"

  # 0x1087 CKM_AES_GCM
  mechanism      = 0x1087
}

The wrapping key is an AES-256 key generated directly in
the TSM. The Builder Vault TSM PKCS#11 driver also supports wrapping the root
key with an RSA key pair instead — see RSA Key Support
below.

Fields, per OpenBao's pkcs11 seal reference:

  • lib (required) — path to the TSM PKCS#11 driver inside the
    container/host.
  • slot — PKCS#11 slot number. token_label is the documented alternative if you need
    to select a slot by token label instead.
  • pin (required) — the PKCS#11 user PIN configured in pkcs11.toml.
  • key_label (required) — label of the AES key used to wrap OpenBao's
    root key. This key must already exist in the TSM before OpenBao starts
    — see Manual Key Provisioning.
  • mechanism — 0x1087 (CKM_AES_GCM) for an AES wrapping key, as used in
    this configuration. 0x0009 (CKM_RSA_PKCS_OAEP) is also supported by
    both the driver and OpenBao's pkcs11 seal for an RSA wrapping key — see
    RSA Key Support below.

OpenBao's pkcs11 seal also supports key_id (hex key identifier),
rsa_oaep_hash (relevant only to the RSA path), and
disable_software_encryption, none of which are used in this AES
configuration.

There is no generate_key parameter. OpenBao's pkcs11 seal
has no generate_keyfield. The wrapping key cannot be created automatically
by OpenBao itself — that's why the manual provisioning step below is
required.

Manual Key Provisioning

Before running bao operator init for the first time, create the AES-256
key that key_label refers to, directly via pkcs11-tool:

pkcs11-tool --module /opt/sepior/tsm-pkcs11.so \
  --slot 0 --login --pin "some password" \
  --keygen --key-type AES:32 \
  --label bao-root-key --id 01 \
  --private --sensitive \
  --usage-decrypt \
  --allowed-mechanisms AES-GCM

If this step is skipped, OpenBao fails to unseal because the key that
pkcs11.hcl expects does not exist in the TSM.

RSA Key Support

Besides the AES/CKM_AES_GCM above, the Builder Vault TSM PKCS#11
driver also implements CKM_RSA_PKCS_OAEP (0x0009) encrypt/decrypt, and
OpenBao's pkcs11 seal wrapper can drive an RSA-wrapped root key through
this mechanism instead of AES.

seal "pkcs11" {
  lib            = "/opt/sepior/tsm-pkcs11.so"
  slot           = 0
  pin            = "some password"
  key_label      = "bao-root-rsa-key"

  # 0x0009 CKM_RSA_PKCS_OAEP
  mechanism      = 0x0009
  rsa_oaep_hash  = "sha256"
}
  • mechanism — 0x0009 (CKM_RSA_PKCS_OAEP). This is the only RSA
    mechanism OpenBao's pkcs11 seal will drive for wrap/unwrap; the driver
    also implements CKM_RSA_PKCS (PKCS#1 v1.5) and CKM_RSA_X_509 for
    encrypt/decrypt, but OpenBao's seal wrapper only recognizes
    CKM_RSA_PKCS_OAEP (or CKM_RSA_PKCS_PSS, which is for signing and not
    used by the seal) — passing another RSA mechanism causes OpenBao to
    reject it with unsupported RSA key mechanism.
  • rsa_oaep_hash — the OAEP hash: sha1, sha224, sha256 (default),
    sha384, or sha512.
  • Supported RSA key sizes: 2048–4096 bits.

RSA key generation is not supported by the BV driver — unlike the AES
option, there is no pkcs11-tool --keygen equivalent here. C_GenerateKeyPair
is an unimplemented PKCS#11 function in the driver, so the RSA key pair
referenced by key_label/key_id must be generated externally to Builder
Vault and provisioned into the TSM before OpenBao's first operator init,
via one of:

  • C_CreateObject — importing raw key material directly.
  • C_UnwrapKey — unwrapping a key that arrives pre-encrypted.

Environment Variables

BAO_ADDR=http://127.0.0.1:8200

BAO_ADDR is OpenBao's preferred address variable for the bao CLI
(VAULT_ADDR is accepted only as a legacy fallback). The config file path
is passed explicitly to the server process via -config, e.g.:

bao server -config /opt/openbao/pkcs11.hcl

No license-related environment variable is required.

Note: the TSM driver also needs to find pkcs11.toml. This setup
does not set an explicit env var for that path — pkcs11.toml is placed
in the process's working directory, which the driver appears to fall
back to. This hasn't been confirmed against the driver's own
documentation, so if the seal fails to find its TSM config, setting the
driver's config-path env var explicitly is the first thing to check.

Initialization Commands

  1. Start OpenBao: bao server -config /opt/openbao/pkcs11.hcl
  2. Provision the unseal-wrapping key in the TSM (once): run the
    pkcs11-tool command above.
  3. Initialize: bao operator init -recovery-shares=1 -recovery-threshold=1
    — -recovery-shares/-recovery-threshold apply specifically to
    auto-unseal seals (HSM/KMS/Transit); a Shamir-sealed OpenBao would use
    -key-shares/-key-threshold instead.
  4. Authenticate with the generated root token.

Limitations

  • Only CKM_AES_GCM (0x1087, AES) and CKM_RSA_PKCS_OAEP (0x0009, RSA)
    are usable by OpenBao's pkcs11 seal against the TSM driver — see
    RSA Key Support for the RSA path.
  • The wrapping key must be pre-provisioned in the TSM before first init —
    OpenBao's pkcs11 seal has no key-generation parameter. For AES this is
    done via pkcs11-tool --keygen; RSA key pairs can't be generated in the
    TSM at all (C_GenerateKeyPair is unimplemented) and must be imported
    externally instead.

References