Vault — API Surface#

API types#

Vault exposes four distinct API surfaces:

  1. REST/HTTP API — the primary user-facing interface for all secret operations
  2. gRPC (internal) — cluster request forwarding, HCP link, and plugin communication
  3. CLI — the vault binary, wrapping the REST API
  4. 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:

  1. 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.
  2. Dynamic routes — all /v1/sys/ and /v1/ paths fall through to handleLogical, which forwards to Core.HandleRequest → radix-tree Router → mounted logical.Backend. Backend paths are registered at mount time (e.g. mounting a KV engine at secret/ makes all GET /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 ServeMux

Additional optional wrappers (controlled by listener config):

  • cleanhttp.PrintablePathCheckHandler — reject non-printable chars in paths
  • disableReplicationStatusEndpointWrapping — suppress replication endpoints
  • redactionSettingsWrapping — redact addresses/version/cluster name in responses
  • wrapRequestLimiterHandler — concurrency limiter

The generic wrapper (wrapGenericHandler) adds:

  • Request timeout enforcement (MaxRequestDuration)
  • Panic recovery with structured logging
  • X-Content-Type-Options: nosniff + X-Frame-Options: DENY headers
  • 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-TTL header 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-Namespace header 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)#

PathPurpose
POST /v1/sys/initInitialize a new Vault cluster (generate root key)
GET/POST /v1/sys/seal-statusCheck seal/unseal state
PUT /v1/sys/unsealSubmit a Shamir unseal key share
PUT /v1/sys/sealSeal Vault (requires root token)
GET /v1/sys/healthHealth check (unauthenticated, returns HTTP status codes)
GET /v1/sys/leaderCurrent HA leader info
PUT /v1/sys/generate-root/attemptBegin root token generation ceremony
PUT /v1/sys/generate-root/updateSubmit OTP share for root generation
PUT /v1/sys/rekey/initBegin rekey ceremony
PUT /v1/sys/storage/raft/bootstrapBootstrap Raft cluster
PUT /v1/sys/storage/raft/joinJoin a Raft cluster
GET /v1/sys/metricsPrometheus/JSON telemetry (optionally unauthenticated)
GET /v1/sys/pprof/*Go pprof profiling (optionally unauthenticated)
GET /v1/sys/in-flight-reqIn-flight request log (optionally unauthenticated)
GET /v1/sys/monitorLog streaming endpoint
GET /v1/sys/internal/ui/feature-flagsUI 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:

ServiceKey RPCsPurpose
BackendHandleRequest, HandleExistenceCheck, SpecialPaths, Setup, Initialize, Cleanup, InvalidateKey, TypeCore plugin contract — Core calls into the plugin
StorageList, Get, Put, DeletePlugin calls back into Vault’s barrier storage
SystemViewDefaultLeaseTTL, MaxLeaseTTL, EntityInfo, GroupsForEntity, ResponseWrapData, GeneratePasswordFromPolicy, GenerateIdentityToken, RegisterRotationJob, DeregisterRotationJob, GetRotationInformationPlugin calls back to read system state
EventsSendEventPlugin emits events into Vault’s event bus
ObservationsRecordObservationPlugin 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
  • HCPLinkMeta — node status and metadata for HashiCorp Cloud Platform integration
  • HCPLinkControl — 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 secret

Other 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 write

Flag 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-token file; pluggable via tokenhelper.TokenHelper interface
  • Special modes: --output-curl-string intercepts 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:

  1. In-process (built-in): Plugin factory functions registered in command/commands.go and helper/builtinplugins/. Core calls the factory directly; no subprocess.
  2. 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/SystemView proto services. Vault cannot distinguish in-process from out-of-process — both implement logical.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#

TypeInterfaceWhere 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 backendsaudit.BackendCoreConfig.AuditBackends map; sys/audit API at runtime
Physical storage backendssdk/physical.Backendcommand/commands.go physicalBackends map; server config only
Seal mechanismsvault/seal.Sealcommand/commands.go seal factory map; server config only
Service registrationsdk/physical/ha.ServiceRegistrationcommand/commands.go serviceRegistrations map
Database pluginssdk/database/dbplugin.Databaseregistered 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 management
  • client.Sys()*api.Sys — management operations (init, seal, unseal, mounts, policies, leases, health, replication)
  • client.KVv1(mount)*api.KVv1 — typed KV v1 helper
  • client.KVv2(mount)*api.KVv2 — typed KV v2 helper with metadata/versioning
  • client.SSHHelper(config) → SSH OTP validation helper
  • client.NewLifetimeWatcher(input)*api.LifetimeWatcher — background goroutine that auto-renews leases/tokens

Key types:

  • api.Config — server address, TLS config, HTTP client, retry policy, timeout
  • api.Secret — universal response wrapper (Data map[string]interface{}, Auth *SecretAuth, WrapInfo *SecretWrapInfo, LeaseID, LeaseDuration)
  • api.LifetimeWatcher — lease renewal loop with channel-based result delivery
  • api.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.