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 sharingKey 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=falseRecovery 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
sealblocks in the server config (command/server/config.go). - Used by
vault.Corefor Init, Seal, Unseal, Rekey, RekeyRecovery. - Persisted seal config lives at
core/seal-configin storage. vault read sys/seal-statusreturns the current state.- For operator workflows see Auto-unseal.
Entry points for modification
- Add a new auto-unseal vendor: implement a
wrapping.Wrapperingo-kms-wrappingand register it fromcommand/server.go'ssetSeal. - Tweak the keyring format: see
vault/keyring.goand the seal config persistence invault/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.