Open-Source Wikis

/

Vault

/

Vault

/

Architecture

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 --> Phys

The 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 response

The 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:

  1. 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.
  2. 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.
  3. 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.go and helper/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 .-> C1

Languages 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.

Architecture – Vault wiki | Factory