Vault — API Surface#
API types#
Vault exposes four distinct API surfaces:
- REST/HTTP API — the primary user-facing interface for all secret operations
- gRPC (internal) — cluster request forwarding, HCP link, and plugin communication
- CLI — the
vaultbinary, wrapping the REST API - Library (
api/module) — the Go client SDK, published as an independent module
REST/HTTP API#
Router#
stdlib net/http.ServeMux — no third-party router. Route registration is explicit and imperative in http/handler.go:handlerWithUnauthRekey(). Vault’s own radix-tree Router (in vault/router.go) handles dynamic backend dispatch for /v1/* paths beyond the handful of hard-coded sys/ routes.
Route registration#
Routes are registered in two layers:
- Static routes — a fixed set of
sys/management endpoints registered directly on the stdlib mux (e.g./v1/sys/init,/v1/sys/unseal,/v1/sys/health). These bypass or get special handling before reaching Core. - Dynamic routes — all
/v1/sys/and/v1/paths fall through tohandleLogical, which forwards toCore.HandleRequest→ radix-treeRouter→ mountedlogical.Backend. Backend paths are registered at mount time (e.g. mounting a KV engine atsecret/makes allGET /v1/secret/*live immediately).
Middleware chain#
Applied outermost-first (listed from outermost to innermost):
WrapRequestPriorityHandler — assign X-Vault-Request-Priority
wrapTokenHeaderSizeHandler — enforce token header byte limit
wrapMaxRequestSizeHandler — enforce body size limit
entWrapGenericHandler — enterprise: namespace injection, audit logging
rateLimitQuotaWrapping — rate-limit quota enforcement (global)
wrapJSONLimitsHandler — JSON depth/length limits
withRoleRateLimitQuotaWrapping — role-based rate-limit quotas
wrapCORSHandler — CORS preflight handling
wrapHelpHandler — ?help=1 path fallback
→ stdlib ServeMuxAdditional optional wrappers (controlled by listener config):
cleanhttp.PrintablePathCheckHandler— reject non-printable chars in pathsdisableReplicationStatusEndpointWrapping— suppress replication endpointsredactionSettingsWrapping— redact addresses/version/cluster name in responseswrapRequestLimiterHandler— concurrency limiter
The generic wrapper (wrapGenericHandler) adds:
- Request timeout enforcement (
MaxRequestDuration) - Panic recovery with structured logging
X-Content-Type-Options: nosniff+X-Frame-Options: DENYheaders- HSTS header for HTTPS listeners
- Cross-cluster request forwarding to the active node
Authentication#
All requests require an X-Vault-Token header carrying a Vault token. The token is validated by Core.HandleRequest via TokenStore.Lookup before any ACL check. Additional mechanisms:
- Response wrapping:
X-Vault-Wrap-TTLheader causes the response to be wrapped in a single-use cubbyhole token rather than returned inline — a security primitive for secret delivery - Namespace routing (enterprise):
X-Vault-Namespaceheader or URL prefix selects the target namespace - Client certificates: supported on listeners but auth method-level (cert auth backend handles validation)
Key endpoints (static sys/ routes in handler.go)#
| Path | Purpose |
|---|---|
POST /v1/sys/init | Initialize a new Vault cluster (generate root key) |
GET/POST /v1/sys/seal-status | Check seal/unseal state |
PUT /v1/sys/unseal | Submit a Shamir unseal key share |
PUT /v1/sys/seal | Seal Vault (requires root token) |
GET /v1/sys/health | Health check (unauthenticated, returns HTTP status codes) |
GET /v1/sys/leader | Current HA leader info |
PUT /v1/sys/generate-root/attempt | Begin root token generation ceremony |
PUT /v1/sys/generate-root/update | Submit OTP share for root generation |
PUT /v1/sys/rekey/init | Begin rekey ceremony |
PUT /v1/sys/storage/raft/bootstrap | Bootstrap Raft cluster |
PUT /v1/sys/storage/raft/join | Join a Raft cluster |
GET /v1/sys/metrics | Prometheus/JSON telemetry (optionally unauthenticated) |
GET /v1/sys/pprof/* | Go pprof profiling (optionally unauthenticated) |
GET /v1/sys/in-flight-req | In-flight request log (optionally unauthenticated) |
GET /v1/sys/monitor | Log streaming endpoint |
GET /v1/sys/internal/ui/feature-flags | UI feature flags (unauthenticated) |
Dynamic sys/ endpoints (handled by the system logical backend, authenticated):
/v1/sys/mounts, /v1/sys/auth, /v1/sys/policies, /v1/sys/leases, /v1/sys/audit, /v1/sys/plugins, /v1/sys/namespaces, /v1/sys/quotas, /v1/sys/replication, /v1/sys/wrapping, /v1/sys/rotate, /v1/sys/step-down, and many more — all routed through Core’s logical dispatch.
Secret engine paths (dynamic): /v1/<mount>/* — every mounted backend’s paths are accessible here. Built-in engines include secret/ (KV v1/v2), pki/, database/, ssh/, transit/, aws/, consul/, nomad/, totp/, rabbitmq/, and identity/.
Auth method paths: /v1/auth/<mount>/login and per-backend configuration paths. Built-in auth methods: token/, approle/, aws/, cert/, github/, ldap/, okta/, oidc/, radius/, userpass/, kubernetes/.
gRPC API#
Vault uses gRPC internally — it is not a public user-facing gRPC API. Proto files are in sdk/plugin/pb/, vault/, vault/hcp_link/proto/, and sdk/database/dbplugin/.
Services#
Plugin communication (sdk/plugin/pb/backend.proto)#
The core plugin RPC surface — used when an external plugin process communicates with Vault over a hashicorp/go-plugin mTLS gRPC connection:
| Service | Key RPCs | Purpose |
|---|---|---|
Backend | HandleRequest, HandleExistenceCheck, SpecialPaths, Setup, Initialize, Cleanup, InvalidateKey, Type | Core plugin contract — Core calls into the plugin |
Storage | List, Get, Put, Delete | Plugin calls back into Vault’s barrier storage |
SystemView | DefaultLeaseTTL, MaxLeaseTTL, EntityInfo, GroupsForEntity, ResponseWrapData, GeneratePasswordFromPolicy, GenerateIdentityToken, RegisterRotationJob, DeregisterRotationJob, GetRotationInformation | Plugin calls back to read system state |
Events | SendEvent | Plugin emits events into Vault’s event bus |
Observations | RecordObservation | Plugin records telemetry observations |
Database plugin (sdk/database/dbplugin/v5/proto/database.proto)#
Specialized plugin interface for database secret engines:
Initialize,NewUser,UpdateUser,DeleteUser,Type,Close
Request forwarding (vault/request_forwarding_service.proto)#
RequestForwarding.ForwardRequest— used by standby nodes to forward writes to the active leader in HA mode
HCP link (vault/hcp_link/proto/)#
HCPLinkMeta— node status and metadata for HashiCorp Cloud Platform integrationHCPLinkControl— control plane channel for HCP-managed Vault clusters
Interceptors#
Not applicable — gRPC is internal-only; standard go-plugin TLS handshake provides authentication between Vault and plugins.
CLI#
Framework#
hashicorp/cli (not Cobra). Commands are registered in command/commands.go as cli.CommandFactory functions (lazy instantiation). The CLI binary is vault.
Command structure#
Common commands (shown prominently in help):
vault read — Read a secret or config path
vault write — Write/create a secret or config
vault delete — Delete a secret
vault list — List secrets or config under a path
vault login — Authenticate and cache a token
vault agent — Run Vault Agent (auto-auth, templating, proxy)
vault server — Run a Vault server
vault status — Show seal/HA status
vault unwrap — Unwrap a response-wrapped secretOther command groups:
vault audit {disable, enable, list}
vault auth {disable, enable, help, list, move, tune}
vault debug
vault kv {delete, destroy, enable-versioning, get, list, metadata get/put/patch/delete, patch, put, rollback, undelete}
vault lease {lookup, renew, revoke}
vault monitor
vault namespace {create, delete, list, lock, lookup, patch, unlock}
vault operator {diagnose, generate-root, init, key-status, members, migrate, raft {autopilot get/set-config/state, join, list-peers, remove-peer, snapshot {inspect,restore,save}}, rekey, rotate, seal, step-down, unseal, usage, utilization}
vault patch
vault path-help
vault pki {health-check, issue, list-intermediates, reissue, verify-sign}
vault plugin {deregister, info, list, register, reload, reload-status, runtime {deregister, info, list, register}}
vault policy {delete, fmt, list, read, write}
vault print {token}
vault proxy — Run Vault Proxy (caching proxy for Vault API)
vault read
vault secrets {disable, enable, list, move, tune}
vault ssh
vault token {capabilities, create, lookup, renew, revoke}
vault transform {decode, encode, import-key, list-alphabet, list-roles, list-templates, list-transformations}
vault transit {import, import-version}
vault version
vault version-history
vault writeFlag patterns#
- Global flags:
--format={table,json,yaml},--detailed,--output-curl-string(print equivalent curl command),--output-policy(print HCL policy for the operation) - Persistent connection flags (on
BaseCommand):-address,-ca-cert,-ca-path,-client-cert,-client-key,-tls-skip-verify,-namespace,-token,-mfa - Environment variable binding: All connection flags bind to
VAULT_*env vars (e.g.VAULT_ADDR,VAULT_TOKEN,VAULT_NAMESPACE,VAULT_CACERT) - Token caching:
~/.vault-tokenfile; pluggable viatokenhelper.TokenHelperinterface - Special modes:
--output-curl-stringintercepts the HTTP call and prints the equivalent curl, enabling discovery without making the actual request
Plugin / Extension system#
Mechanism#
Dual-mode plugin system using hashicorp/go-plugin:
- In-process (built-in): Plugin factory functions registered in
command/commands.goandhelper/builtinplugins/. Core calls the factory directly; no subprocess. - Out-of-process (external): Plugin binary is launched as a subprocess. Vault and the plugin communicate over a local mTLS gRPC connection using the
Backend/Storage/SystemViewproto services. Vault cannot distinguish in-process from out-of-process — both implementlogical.Backend.
External plugin multiplexing (since Vault 1.12): a single plugin binary can serve multiple mount instances via sdk/helper/pluginutil multiplexing, reducing process overhead.
Extension points#
| Type | Interface | Where registered |
|---|---|---|
| Auth methods (credential backends) | sdk/logical.Backend (type=Credential) | CoreConfig.CredentialBackends map; sys/auth API at runtime |
| Secret engines (logical backends) | sdk/logical.Backend (type=Logical) | CoreConfig.LogicalBackends map; sys/mounts API at runtime |
| Audit backends | audit.Backend | CoreConfig.AuditBackends map; sys/audit API at runtime |
| Physical storage backends | sdk/physical.Backend | command/commands.go physicalBackends map; server config only |
| Seal mechanisms | vault/seal.Seal | command/commands.go seal factory map; server config only |
| Service registration | sdk/physical/ha.ServiceRegistration | command/commands.go serviceRegistrations map |
| Database plugins | sdk/database/dbplugin.Database | registered as a secret engine plugin, special sub-protocol |
Built-in plugins#
Auth methods: approle, aws, cert, github, ldap, okta, oidc/jwt, radius, token, userpass, kubernetes (enterprise adds more)
Secret engines: aws, consul, database, kv (v1+v2), nomad, pki, pkiext, rabbitmq, ssh, totp, transit, cubbyhole, identity, system
Audit backends: file, socket, syslog
Plugin catalog#
The vault/plugincatalog.PluginCatalog manages registered plugin metadata. Operators register external plugins with vault plugin register (providing binary path + SHA256). The catalog stores entries in the barrier and resolves them at mount time.
Library API#
Public packages (api/ module — github.com/hashicorp/vault/api)#
The api/ module is an independent Go module (separate go.mod) with minimal dependencies. It is the canonical way for external programs to interact with Vault.
Main entry point: api.Client
config := api.DefaultConfig() // reads VAULT_ADDR, VAULT_TOKEN, etc.
client, err := api.NewClient(config)
client.SetToken("s.xxx")Core client methods:
client.Logical()→*api.Logical— raw CRUD:Read(path),Write(path, data),Delete(path),List(path),ReadWithContext,WriteWithContext, etc.client.Auth()→*api.Auth— auth token managementclient.Sys()→*api.Sys— management operations (init, seal, unseal, mounts, policies, leases, health, replication)client.KVv1(mount)→*api.KVv1— typed KV v1 helperclient.KVv2(mount)→*api.KVv2— typed KV v2 helper with metadata/versioningclient.SSHHelper(config)→ SSH OTP validation helperclient.NewLifetimeWatcher(input)→*api.LifetimeWatcher— background goroutine that auto-renews leases/tokens
Key types:
api.Config— server address, TLS config, HTTP client, retry policy, timeoutapi.Secret— universal response wrapper (Data map[string]interface{},Auth *SecretAuth,WrapInfo *SecretWrapInfo,LeaseID,LeaseDuration)api.LifetimeWatcher— lease renewal loop with channel-based result deliveryapi.TLSConfig— TLS configuration for mutual TLS
API style#
Method-based on structs. No functional options on the main Client — configuration is via the Config struct at construction time. Functional options appear only in newer helpers (e.g. KVv2.WithOption, KVv2.WithCheckAndSet).
Response callbacks: api.RecordState(state *string) and api.RequireState(states...) implement consistency tokens for performance standbys (similar to read-your-writes tokens in distributed databases).
Backward compatibility#
The api/ module maintains strong backward compatibility — it is versioned separately from the main module at v1.x.x. The sdk/ module similarly maintains independent versioning for plugin authors. No breaking changes within a major version; deprecated fields/methods are retained for multiple release cycles.
Plugin helper library#
api.VaultPluginTLSProvider / api.VaultPluginTLSProviderContext — helpers for plugin authors to establish the mTLS channel back to Vault during the plugin handshake (read VAULT_* env vars injected by go-plugin).
api/auth/ sub-packages: typed auth method helpers (e.g. api/auth/aws, api/auth/kubernetes, api/auth/approle) that wrap client.Auth().Login() with method-specific credential building.