hashicorp/vault
Architecture
Vault is a single Go binary that hosts an HTTP/gRPC server, a request router, a pluggable storage backend, an extensible plugin system for auth and secret engines, and a UI. This page traces a request from the wire to a backend and back so you can find your way through the source.
Process layout
graph TD
subgraph Client
CLI[vault CLI<br/>command/]
SDK[Go API client<br/>api/]
UI[Web UI<br/>ui/]
Other[REST clients]
end
subgraph "Vault server (one Go binary)"
Listener[TLS/HTTP listener<br/>internalshared/listenerutil]
Handler[HTTP mux<br/>http/handler.go]
Core[Core<br/>vault/core.go]
Router[Router<br/>vault/router.go]
Mounts[Mount tables<br/>vault/mount.go]
Auth[Auth methods]
Secrets[Secret engines]
ID[Identity store<br/>vault/identity_store.go]
ACL[Policy/ACL<br/>vault/policy_store.go]
Exp[Expiration manager<br/>vault/expiration.go]
Audit[Audit broker<br/>audit/]
end
subgraph "Storage layer"
Barrier[AES-GCM barrier<br/>vault/barrier_aes_gcm.go]
Phys[Physical backend<br/>physical/, sdk/physical/]
end
Client --> Listener --> Handler --> Core
Core --> Router
Router --> Mounts
Router --> Auth
Router --> Secrets
Core --> ID
Core --> ACL
Core --> Exp
Core --> Audit
Core --> Barrier --> PhysThe numbered components above each have their own page in Systems.
Request lifecycle
A Vault read or write travels through roughly the same nine stages:
sequenceDiagram
participant C as Client
participant H as http/handler.go
participant Core as vault.Core
participant ACL as Policy/ACL
participant R as Router
participant B as Backend
participant E as Expiration
participant A as Audit broker
participant S as Storage barrier
C->>H: HTTP request (X-Vault-Token, body)
H->>Core: HandleRequest(req)
Core->>Core: lookup token in token store
Core->>ACL: derive policy + check capabilities
Core->>A: log request (HMAC sensitive fields)
Core->>R: route by mount path
R->>B: backend.HandleRequest(req)
B->>S: read/write encrypted data
B-->>R: logical.Response (+ optional Secret/Auth)
R-->>Core: response
Core->>E: register lease if Secret/Auth lease present
Core->>A: log response
Core-->>H: response
H-->>C: HTTP responseThe bulk of this flow is implemented in vault/request_handling.go (3,140 lines) which wraps vault/core.go (5,042 lines).
Storage stack
Vault never writes to disk directly. Every byte that leaves the process passes through three layers:
- Backend storage view (
logical.Storage,sdk/logical/storage.go) — the per-mount, namespaced view a backend sees. Keys are prefixed with the mount UUID so backends cannot read each other's data. - Encryption barrier (
vault/barrier_aes_gcm.go) — AES-256-GCM encryption with a keyring that is itself sealed by the master key. Every write is authenticated; tampering or partial writes are detected on read. - Physical backend (
physical/,sdk/physical/inmem) — the raw key-value store. Implementations include integrated Raft (physical/raft), Consul, PostgreSQL, MySQL, DynamoDB, S3, GCS, Azure Blob, and many more.
The barrier is initialized at unseal time. Until enough unseal keys (or an auto-unseal KMS) reconstruct the master key the barrier stays locked and the API rejects most requests with ErrSealed. See Seal and Auto-unseal.
Plugin model
Auth methods, secret engines, and database plugins implement the logical.Backend interface from sdk/logical/logical.go. The router maps URL prefixes to backends via the mount table. Two kinds of plugins exist:
- Built-in — compiled into the binary and registered in
helper/builtinplugins/registry.goandhelper/builtinplugins/registry_full.go. Examples:pki,kv,transit,userpass,approle. - External — separate binaries launched as subprocesses over gRPC using
sdk/plugin. The plugin catalog (vault/plugincatalog/) tracks registered plugins and verifies their checksums.
See Plugin system and Plugin catalog.
High availability
In HA mode each Vault instance starts as a standby and one node holds the leader lock in storage. Only the active node handles writes; standbys forward requests via a gRPC channel implemented in vault/request_forwarding.go and vault/request_forwarding_service.proto. With integrated storage the leader election piggybacks on Raft (vault/raft.go, physical/raft/); with Consul/etcd backends the lock comes from the storage backend itself. See Raft and HA.
Multi-cluster topology
Enterprise builds add disaster-recovery (DR) and performance replication. The OSS tree contains the seams where these systems hook in (vault/replication/, replication_status.go) but not the full implementation.
graph LR
subgraph "Region A (primary)"
A1[Active]
A2[Standby]
A3[Standby]
end
subgraph "Region B (DR)"
B1[DR active]
B2[DR standby]
end
subgraph "Region C (perf secondary)"
C1[Active]
C2[Standby]
end
A1 -. WAL replication .-> B1
A1 -. WAL replication .-> C1Languages and lines
The repository is dominated by Go, with a sizable Ember.js web UI:
xychart-beta horizontal
title "Lines of code by language (excluding tests)"
x-axis ["Go", "JS/TS/Hbs/Scss (UI)"]
y-axis "Lines" 0 --> 400000
bar [390020, 33738]Tests are extensive: 773 *_test.go files account for ~310k additional lines.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.