Skip to main content

OpenBao Unseal Mechanisms

OpenBao encrypts everything it stores under a root key. That root key is itself protected ("sealed") and has to be decrypted into memory before OpenBao can serve any request. Every time an OpenBao process starts or restarts, it comes up sealed, and stays unusable until it's unsealed again.

Shamir's Secret Sharing (the default)

By default, OpenBao protects the root key using Shamir's Secret Sharing: the key is split into a number of key shares, and a threshold of those shares has to be supplied one at a time, by a human, via bao operator unseal, before OpenBao reconstructs the root key and unseals.

This works well for a single long-lived server that rarely restarts. It's impractical in Kubernetes: pods restart, reschedule, and scale routinely and unattended, and each of those events reseals OpenBao again. Requiring a human to manually supply unseal shares every time that happens doesn't fit a self-healing, automated deployment: there often isn't anyone watching, and GitOps is built around changes applying themselves without a person in the loop.

Auto-unseal

To solve this, OpenBao can delegate protection of the root key to an external mechanism instead of Shamir shares. On startup, OpenBao asks that mechanism to decrypt an encrypted copy of its root key, and unseals automatically, with no human and no manual shares involved.

Static key seal in the HavenPlus reference implementation

The HavenPlus reference implementation currently uses the simplest form of auto-unseal: a static key seal. A random key is generated once and stored as a Kubernetes Secret in the same cluster, then injected into OpenBao so it can auto-unseal on startup without any manual step.

This is a deliberate, known trade-off, not a production recommendation: the thing protecting the sealed data is itself just a Kubernetes Secret sitting in the same cluster as the data it protects. Anyone able to read that Secret (or exec into a pod that mounts it) can unseal OpenBao, so there's no separation between "the cluster is compromised" and "the vault is compromised". A real production deployment should use a KMS or HSM instead, which is what the rest of this guide is about.

What's a KMS? What's an HSM?

A KMS (Key Management Service) is a managed service, usually cloud-hosted, that stores and manages encryption keys and performs encrypt/decrypt operations on request via an API, without ever handing the raw key material back to the caller.

An HSM (Hardware Security Module) is a dedicated, tamper-resistant hardware device (or a cloud-hosted equivalent) that stores keys and performs cryptographic operations inside the hardware itself, so the key material never leaves the device.

Either way, OpenBao uses the same pattern for auto-unseal: instead of storing or deriving the unseal key itself, OpenBao sends an encrypted copy of its root key to the KMS/HSM and asks it to decrypt it on startup. The key material that actually protects the data never leaves the KMS/HSM boundary, so a cluster compromise alone doesn't get you the seal key too.

Supported options in OpenBao

OpenBao supports several seal mechanisms out of the box (see the full seal configuration reference for setup details):

  • Shamir: the manual, threshold-based default described above.
  • Static Key: the simple in-cluster key described above.
  • PKCS#11: a hardware or virtual HSM speaking the PKCS#11 standard.
  • AWS KMS, Azure Key Vault, GCP Cloud KMS, AliCloud KMS, OCI KMS, OVHcloud KMS, Tencent Cloud KMS: cloud-provider-managed KMS services.
  • KMIP: an HSM or key manager speaking the Key Management Interoperability Protocol.
  • OpenBao Transit: another OpenBao (or Vault) instance's Transit secrets engine, used as the unseal mechanism. See below.

When no cloud/SaaS KMS is available: OpenBao Transit

None of the cloud KMS options apply if the environment has no access to a cloud provider, for example an on-premises or air-gapped deployment. In that case, the Transit seal lets you build the equivalent of a KMS yourself: one dedicated OpenBao instance acts as a root of trust, with its Transit secrets engine enabled and an encryption key created in it. Other OpenBao instances then auto-unseal by calling that root instance over the network (address, token, key name, and mount path) and asking it to encrypt/decrypt their root key, instead of each needing its own KMS or HSM.

That root instance still has to be sealed and unsealed itself by some other means, typically Shamir, done manually once. Transit doesn't remove the unsealing problem entirely; it concentrates it into a single, dedicated instance instead of every OpenBao deployment having to solve it independently.