Open-Source Wikis

/

Vault

/

Features

/

Auto-unseal

hashicorp/vault

Auto-unseal

Auto-unseal replaces the human Shamir-share workflow with an external KMS that wraps Vault's keyring. After the first init, every subsequent start unseals automatically — there's no operator in the loop. Implementation: vault/seal_autoseal.go, vault/seal/, with vendor wrappers from hashicorp/go-kms-wrapping/v2.

Why operators want it

Shamir is a great property for "the human in the room owns this Vault." It's a poor fit for autoscaling clusters, container restarts, or multi-region deployments where you can't pre-stage humans for every unseal event. Auto-unseal trades the threshold ceremony for trust in a cloud KMS or HSM.

Supported seal types

The seal block in the server config selects the type. Each maps to a specific wrapper in go-kms-wrapping:

seal "..." block KMS / HSM Notes
awskms AWS KMS IAM credentials or instance role.
gcpckms Google Cloud KMS service account or workload identity.
azurekeyvault Azure Key Vault service principal or managed identity.
ocikms Oracle Cloud KMS OCI principal config.
transit Another Vault cluster's transit engine Useful for "Vault unseals Vault" patterns.
pkcs11 (Enterprise) HSM via PKCS#11 Closed-source.
aead Local AEAD Test only.

The wrappers themselves come from github.com/hashicorp/go-kms-wrapping/v2 and wrappers/<name>/v2 modules.

Configuration

storage "raft" {
  path    = "/vault/data"
  node_id = "vault-1"
}

seal "awskms" {
  region     = "us-east-1"
  kms_key_id = "alias/vault-seal"
}

listener "tcp" {
  address     = "0.0.0.0:8200"
  tls_cert_file = "/etc/vault/tls/cert.pem"
  tls_key_file  = "/etc/vault/tls/key.pem"
}

Multiple seal blocks are allowed (Enterprise) so the keyring is wrapped redundantly across vendors.

How it works

sequenceDiagram
    participant V as Vault start
    participant Seal as autoSeal
    participant KMS as External KMS
    participant Phys as Storage
    V->>Phys: read core/seal-config and core/keyring
    V->>Seal: Unseal with stored ciphertext
    Seal->>KMS: Decrypt(ciphertext)
    KMS-->>Seal: keyring plaintext
    Seal->>V: keyring loaded
    V->>V: PostUnseal: mount backends, start expiration, ...

On first init, Vault generates the keyring, encrypts it with the configured KMS key, and stores the ciphertext at core/keyring. On subsequent starts, it reads the ciphertext and asks the KMS to decrypt — no Shamir shares are required.

Recovery key

Even with auto-unseal, some operations (operator generate-root, operator rekey-recovery-key) require human authorization. For those, Vault keeps a separate recovery key that is Shamir-split. vault operator init -recovery-shares=5 -recovery-threshold=3 is the equivalent of Shamir init for an auto-unsealed cluster.

vault/generate_root_recovery.go is the dedicated flow.

Migration

Switching from Shamir to KMS, or from one KMS to another, is supported in-place:

# new seal config
seal "shamir" { disabled = true }
seal "awskms" {
  region     = "us-east-1"
  kms_key_id = "alias/vault-seal"
}

Start the cluster, then run vault operator unseal -migrate <shamir share>. Vault rewraps the keyring with the new wrapper on every node before completing unseal.

Failure modes

  • KMS unreachable at unseal time — Vault stays sealed and retries. The auto_unseal metric reports the consecutive failure count.
  • Wrong KMS key — Vault refuses to unseal; logs recover from sealed configuration.
  • Multi-seal disagreement (Enterprise) — Vault unseals if at least one wrapper succeeds, but logs the lagging wrappers and surfaces them via seal-status.

Integration points

  • Configured in server config.
  • Wraps the seal keyring.
  • The recovery key flow takes the place of operator-level Shamir actions.
  • command/server.go::setSeal builds the seal stack from seal blocks and the entropy block (for HSM-backed entropy augmentation).

Operator commands

  • vault operator init -recovery-shares=… -recovery-threshold=… — initialize an auto-unseal cluster.
  • vault operator generate-root -recovery — start a root-token generation that requires the recovery key.
  • vault operator rekey -target=recovery — rekey the recovery shares.
  • vault operator unseal -migrate — migrate from Shamir to/from auto-unseal.

Entry points for modification

  • New KMS vendor: implement a wrapping.Wrapper in go-kms-wrapping, add the seal "<type>" parser to command/server.go::setSeal.
  • Tweak retry semantics on KMS failure: vault/seal_autoseal.go.
  • Multi-seal redundancy logic: vault/seal/seal.go and vault/seal/seal_wrapper.go.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Auto-unseal – Vault wiki | Factory