hashicorp/vault
Core
vault.Core is the central object instantiated by every Vault server process. It owns the storage barrier, mount tables, token store, identity store, policy store, expiration manager, audit broker, plugin catalog, and the lifecycle that turns a sealed binary into an active cluster member. Source: vault/core.go (5,042 lines) plus dozens of core_*.go siblings.
Purpose
Hold every long-lived subsystem and orchestrate their lifecycle: init → seal → unseal → standby/active → seal → shutdown. Every HTTP request lands in Core.HandleRequest (vault/request_handling.go).
Directory layout
vault/
├── core.go # the Core struct and most lifecycle methods
├── core_metrics.go # periodic metric emission
├── core_metrics_oss.go # CE stub
├── core_stubs_oss.go # CE stubs for Enterprise hooks
├── core_util.go, core_util_common.go
├── request_handling.go # HandleRequest, the per-request pipeline
├── request_handling_ce.go # CE stub
├── ha.go # active/standby state machine, leader election
├── seal.go, seal_*.go # seal/unseal, autoseal, key rotation
├── init.go # first-time initialization (master key, root token)
├── rekey.go # rekey of barrier and recovery keys
├── generate_root.go # operator generate-root flow
├── rollback.go # periodic per-mount rollback ticker
├── policy.go, policy_store.go # policy storage
├── acl.go, acl_util.go # capability checks
├── mount.go # mount tables
├── router.go, router_access.go # URL routing
├── token_store.go # token CRUD
├── identity_store.go (+16 more) # entities, aliases, groups, OIDC
├── expiration.go # leases and renewal
├── login_mfa.go # login-time MFA
├── audit.go # mount/unmount of audit devices
├── quotas/ # rate-limit and lease-count quotas
├── plugincatalog/ # external plugin metadata
├── seal/ # the seal package (separate from seal.go)
├── eventbus/ # in-process pub/sub
├── replication/ # CE replication hooks (mostly stubs)
└── ...Key abstractions
| Symbol | File | Description |
|---|---|---|
Core |
vault/core.go |
The god object. ~150 fields. |
CoreConfig |
vault/core.go |
Configuration passed by command/server.go when constructing a Core. |
NewCore |
vault/core.go |
Constructor; wires up mounts, audit broker, expiration manager, and plugin catalog. |
Core.HandleRequest |
vault/request_handling.go |
Per-request pipeline: identity, policy, audit, route, response. |
Core.Initialize / Core.Init |
vault/init.go |
First-time setup: generate master key, write barrier keyring, mint root token. |
Core.Unseal |
vault/seal.go |
Provide an unseal share or a KMS key to unwrap the keyring. |
Core.Seal / Core.SealAccess |
vault/seal.go, vault/seal_access.go |
Seal the core (shut down handlers and zero the keyring in memory). |
Core.runStandby |
vault/ha.go |
Standby loop that participates in leader election. |
Core.PostUnseal |
vault/core.go |
Hook run after unseal; mounts backends, starts expiration. |
Core.PreSeal |
vault/core.go |
Hook run before seal; flushes audit, stops timers, unmounts backends. |
Core.checkToken |
vault/request_handling.go |
Token + ACL check for an incoming request. |
Lifecycle states
stateDiagram-v2
[*] --> Sealed: NewCore
Sealed --> Initialized: Initialize (first time only)
Sealed --> Unsealing: Unseal (key share or KMS)
Initialized --> Sealed: Seal
Unsealing --> Standby: keyring assembled, not active
Standby --> Active: leader lock acquired
Active --> Standby: leader lock lost
Active --> Sealed: explicit Seal or fatal error
Standby --> Sealed: explicit Seal
Sealed --> [*]: shutdownThe states are exposed through vault read sys/seal-status. The active/standby split lets a cluster member receive requests but forward writes to the active node via vault/request_forwarding.go.
Per-request pipeline
Core.HandleRequest (vault/request_handling.go, 3,140 lines) is the canonical pipeline:
- Resolve namespace and parse path.
- Look up the token in the token store.
- Apply login MFA if the request is a login.
- Check ACL capabilities (
vault/acl.go). - Apply quotas (
vault/quotas/). - Audit-log the request (
audit/). - Route to the backend (
vault/router.go). - If the backend returned a
Secret/Auth, register a lease (vault/expiration.go) or mint a token (vault/token_store.go). - Audit-log the response.
- Return.
Every step has its own helper file (request_handling_util.go, request_handling_ce.go, request_handling_filtered.go, …).
Integration points
- Storage:
Coreholds the physical backend, the barrier, and the keyring; backends only see the storage view supplied by the router. - Listeners: opened by
command/server.go; the HTTP handler calls into Core. - Plugins:
vault/plugincatalog/is owned by Core and passed to backends through their system view. - Replication: hooks at
vault/replication/andvault/forwarded_writer_oss.goare present in OSS but mostly empty. - Metrics:
vault/core_metrics.go(36k lines) emits per-second snapshots of mounts, tokens, leases, audit health.
Entry points for modification
- New lifecycle hook: extend
Core.PostUnseal/Core.PreSealand call your subsystem'sSetup/Teardown. - New per-request step: add to
Core.HandleRequestinvault/request_handling.go. Be careful — every step here must be O(1) in the request size and avoid blocking I/O when possible. - New storage path on
core/: paths undercore/are reserved for Core's own metadata (mount table, keyring, leader lock, …). Don't reuse them.
For step-by-step request behavior see Architecture / request lifecycle.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.