Open-Source Wikis

/

Vault

/

Systems

/

Seal

hashicorp/vault

Seal

The seal is the boundary between a sealed Vault (nothing readable, nothing writable) and an unsealed one (the in-memory keyring is reconstructed and the barrier is open). Source: vault/seal.go, vault/seal_autoseal.go (16k lines), vault/seal_config.go, vault/seal_util.go, plus the standalone vault/seal/ package and shamir/.

Purpose

  • Keep the master key off disk in plaintext at all times.
  • Allow Vault to bootstrap without a human if an external KMS is configured (auto-unseal).
  • Support graceful migration between Shamir and KMS, or between two KMS vendors.

Directory layout

vault/
├── seal.go                     # Seal interface, Shamir seal
├── seal_access.go              # Restricted view passed to subsystems
├── seal_autoseal.go            # KMS-backed seal
├── seal_config.go              # Persisted seal config record
├── seal_util.go                # Helpers for migration
├── seal_wrapped_value.go       # Wire format for a wrapped keyring
├── seal_testing.go, seal_testing_util.go, seal_stubs_oss.go, seal_rewrap_stubs_oss.go, sealunwrapper.go
└── seal/                       # The auto-unseal facade
    ├── seal.go                 # Seal facade for KMS wrappers (35k lines)
    ├── seal_wrapper.go         # multi-wrapper support (HA + redundancy)
    ├── envelope.go             # envelope encryption helpers
    └── multi_wrap_value.pb.go  # protobuf message used for multi-seal
shamir/
└── shamir.go                   # Shamir secret sharing

Key abstractions

Symbol File Description
Seal vault/seal.go The interface every seal implementation satisfies.
defaultSeal vault/seal.go Shamir-based seal: master key is the threshold combination of unseal shares.
autoSeal vault/seal_autoseal.go Wraps the keyring with one or more KMS wrappers via vault/seal/.
SealAccess vault/seal_access.go Restricted handle to the seal that other subsystems can hold without being able to seal/unseal.
Access vault/seal/seal.go The auto-unseal facade. Owns one or more SealWrappers.
SealWrapper vault/seal/seal_wrapper.go A single KMS connection (e.g. AWS KMS, Azure Key Vault, …) wrapped to satisfy the seal interface.
Shares / Combine shamir/shamir.go Shamir threshold scheme.

Seal types (auto-unseal)

Type Wrapper
Shamir (default) vault/seal.go defaultSeal
AWS KMS go-kms-wrapping/wrappers/awskms
Azure Key Vault go-kms-wrapping/wrappers/azurekeyvault
Google Cloud KMS go-kms-wrapping/wrappers/gcpckms
Oracle KMS go-kms-wrapping/wrappers/ocikms
HSM PKCS#11 (Enterprise) closed-source wrapper
Transit go-kms-wrapping/wrappers/transit
AEAD test go-kms-wrapping/wrappers/aead

The set of supported wrappers comes from the hashicorp/go-kms-wrapping/v2 library. command/server.go builds the wrapper stack from the seal blocks in the config.

Unseal flow

sequenceDiagram
    participant Op as Operator/KMS
    participant H as http/handler.go
    participant Core as vault.Core
    participant S as Seal
    participant K as Keyring
    Op->>H: PUT /sys/unseal {key|nonce}
    H->>Core: Unseal(key)
    alt Shamir
        Core->>S: defaultSeal.Unseal(key)
        S-->>Core: more keys needed?
        Core-->>Op: progress n/threshold
        Op->>H: ... (repeat until threshold)
    else Auto-unseal
        Core->>S: autoSeal.unwrap(stored ciphertext)
        S-->>Core: master key
    end
    Core->>K: load keyring with master key
    Core->>Core: PostUnseal: mount backends, start expiration, ...
    Core-->>Op: sealed=false

Recovery key

When Shamir is replaced with auto-unseal, Vault still keeps a recovery key (also Shamir-split) to authorize sensitive operations like operator generate-root or operator rekey-recovery-key. This is what vault/generate_root_recovery.go exists for.

Multi-seal (Enterprise)

vault/seal/seal_wrapper.go and multi_wrap_value.proto support wrapping the keyring with multiple KMS instances, so Vault can survive losing one of them. Access owns the redundancy logic. CE has the plumbing but the production multi-KMS use cases are Enterprise.

Migration

Switching seal type (e.g. Shamir → AWS KMS or AWS KMS → GCP CKMS) is supported via seal "shamir" { disabled = true } and a paired auto-unseal block. seal_util.go and vault/sealmigrationcheckresult_enumer.go drive the in-place rewrap of the keyring on first start.

Integration points

  • Configured in the seal blocks in the server config (command/server/config.go).
  • Used by vault.Core for Init, Seal, Unseal, Rekey, RekeyRecovery.
  • Persisted seal config lives at core/seal-config in storage.
  • vault read sys/seal-status returns the current state.
  • For operator workflows see Auto-unseal.

Entry points for modification

  • Add a new auto-unseal vendor: implement a wrapping.Wrapper in go-kms-wrapping and register it from command/server.go's setSeal.
  • Tweak the keyring format: see vault/keyring.go and the seal config persistence in vault/seal_config.go.
  • Custom recovery flow: extend vault/generate_root_recovery.go.

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

Seal – Vault wiki | Factory