HashiCorp Vault — Vault Architecture
Vault’s architecture is designed around a security-first model where all data is encrypted before it ever reaches storage. Understanding these internals helps you operate Vault confidently in production.
High-Level Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Vault Server │
│ │
│ ┌───────────┐ ┌───────────────┐ ┌────────────┐ │
│ │ HTTP │ │ System │ │ Cluster │ │
│ │ API │ │ Backend │ │ (HA) │ │
│ │ :8200 │ │ │ │ :8201 │ │
│ └─────┬─────┘ └───────┬───────┘ └─────┬──────┘ │
│ │ │ │ │
│ ┌─────▼─────────────────▼─────────────────▼──────────────────┐ │
│ │ Core │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────────┐ ┌────────────────────┐ │ │
│ │ │ Auth │ │ Secrets │ │ Audit │ │ │
│ │ │ Methods │ │ Engines │ │ Devices │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ Token │ │ KV │ │ File │ │ │
│ │ │ AppRole │ │ Database │ │ Syslog │ │ │
│ │ │ OIDC │ │ Transit │ │ Socket │ │ │
│ │ │ K8s │ │ PKI │ │ │ │ │
│ │ │ AWS │ │ AWS/Azure/GCP│ │ │ │ │
│ │ └──────────┘ └──────────────┘ └────────────────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ Token Store │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ Policy Store │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────▼──────────────────────────────┐ │
│ │ Barrier (AES-256-GCM) │ │
│ │ All data encrypted before storage │ │
│ └──────────────────────────┬──────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────▼──────────────────────────────┐ │
│ │ Storage Backend │ │
│ │ │ │
│ │ ┌──────┐ ┌────────┐ ┌───────┐ ┌──────────────┐ │ │
│ │ │ Raft │ │ Consul │ │ S3 │ │ GCS / Azure │ │ │
│ │ └──────┘ └────────┘ └───────┘ └──────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
The Barrier
The barrier is Vault’s most critical architectural component. It provides an encryption layer between Vault and its storage backend.
How it works:
- Vault generates a master key during initialization
- The master key encrypts an encryption key
- The encryption key encrypts all data using AES-256-GCM
- Only encrypted data reaches the storage backend
- The storage backend never sees plaintext
┌────────────────┐ ┌────────────────┐ ┌────────────────┐
│ Unseal Keys │─────▶│ Master Key │─────▶│ Encryption Key │
│ (Shamir's) │ │ │ │ (AES-256-GCM) │
└────────────────┘ └────────────────┘ └────────┬───────┘
│
Encrypts all data
│
▼
┌────────────────┐
│ Storage Backend│
│ (sees only │
│ ciphertext) │
└────────────────┘
💡 Key insight: Even if someone gains access to your storage backend (Raft files, Consul data, S3 bucket), they cannot read any secrets without the unseal keys.
Storage Backend
The storage backend provides durable persistence for Vault’s encrypted data. It does not need to provide encryption — the barrier handles that.
| Backend | HA Support | Description |
|---|---|---|
| Raft (Integrated) | ✅ | Built-in consensus, recommended for most deployments |
| Consul | ✅ | HashiCorp’s service mesh, mature HA support |
| S3 | ❌ | AWS object storage, no HA |
| GCS | ❌ | Google Cloud Storage, no HA |
| Azure Blob | ❌ | Azure object storage, no HA |
| Filesystem | ❌ | Local disk, dev/test only |
Raft is the recommended storage backend for production. It provides built-in HA without external dependencies.
# vault.hcl — Raft storage configuration
storage "raft" {
path = "/opt/vault/data"
node_id = "vault-1"
}
Secrets Engines
Secrets engines are pluggable components mounted at specific paths. Each engine handles a different type of secret.
# List enabled secrets engines
vault secrets list
# Output:
# Path Type Description
# ---- ---- -----------
# cubbyhole/ cubbyhole per-token private storage
# identity/ identity Identity store
# secret/ kv key/value secret storage
# sys/ system system endpoints
How mounting works:
# Enable a database secrets engine at "database/"
vault secrets enable database
# Enable another KV engine at "team-a/"
vault secrets enable -path=team-a kv-v2
Each mount point is an isolated namespace — secret/myapp and team-a/myapp are completely separate.
Auth Methods
Auth methods verify client identity and return a Vault token with attached policies.
┌────────────┐ ┌─────────────┐ ┌───────────┐
│ Client │────▶│ Auth Method │────▶│ Vault │
│ │ │ │ │ Token │
│ Credentials │ │ • Token │ │ │
│ (password, │ │ • AppRole │ │ + Policies│
│ JWT, etc.) │ │ • OIDC │ │ + TTL │
└────────────┘ │ • K8s SA │ │ + Metadata│
└─────────────┘ └───────────┘
# Enable userpass auth method
vault auth enable userpass
# Create a user
vault write auth/userpass/users/sushil \
password="my-password" \
policies="dev-team"
# Login
vault login -method=userpass username=sushil password="my-password"
Audit Devices
Audit devices log every Vault operation. Vault requires at least one working audit device in production — if all audit devices fail, Vault stops responding to prevent unaudited access.
# Enable file audit device
vault audit enable file file_path=/var/log/vault/audit.log
# Enable syslog audit device
vault audit enable syslog tag="vault" facility="AUTH"
Audit log entry example:
{
"type": "request",
"auth": {
"token_type": "service",
"policies": ["default", "dev-team"]
},
"request": {
"operation": "read",
"path": "secret/data/myapp",
"remote_address": "10.0.1.50"
},
"response": {
"data": {
"data": {
"db_password": "hmac-sha256:abc123..."
}
}
}
}
⚠️ Important: Sensitive values in audit logs are HMAC-hashed, not stored in plaintext. You can verify a specific value against the hash if needed.
The Request Lifecycle
When a client makes a request, here’s the complete flow:
Client Request
│
▼
┌─────────────────┐
│ 1. HTTP Listener │ ← Parse request, check TLS
└────────┬────────┘
│
▼
┌─────────────────┐
│ 2. Audit Request │ ← Log the request to audit devices
└────────┬────────┘
│
▼
┌─────────────────┐
│ 3. Authenticate │ ← Validate token, check expiry
└────────┬────────┘
│
▼
┌─────────────────┐
│ 4. Authorize │ ← Check policies for path + capability
└────────┬────────┘
│
▼
┌─────────────────┐
│ 5. Route │ ← Direct to correct secrets engine
└────────┬────────┘
│
▼
┌─────────────────┐
│ 6. Process │ ← Secrets engine handles the request
└────────┬────────┘
│
▼
┌─────────────────┐
│ 7. Audit Response│ ← Log the response to audit devices
└────────┬────────┘
│
▼
Client Response
Ports and Networking
| Port | Purpose | Protocol |
|---|---|---|
| 8200 | Client API & UI | HTTPS (TLS required in production) |
| 8201 | Cluster communication (HA) | HTTPS (mutual TLS) |
# vault.hcl — listener configuration
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/opt/vault/tls/vault-cert.pem"
tls_key_file = "/opt/vault/tls/vault-key.pem"
}
Quick Reference
| Component | Purpose |
|---|---|
| Barrier | Encrypts all data with AES-256-GCM before storage |
| Storage Backend | Persists encrypted data (Raft recommended) |
| Secrets Engines | Generate, store, or encrypt secrets (pluggable) |
| Auth Methods | Verify client identity, issue tokens |
| Audit Devices | Log every operation (HMAC-protected) |
| Token Store | Manages all Vault tokens and their properties |
| Policy Store | Stores and evaluates access control policies |
Next: Seal & Unseal