Vault — Structure#
Layout pattern#
Custom / Monorepo with in-tree sub-modules
Vault does not follow the conventional Go community layout (cmd/, pkg/, internal/). Instead it uses a domain-driven top-level layout where each major concern gets its own directory. Two subdirectories (api/ and sdk/) are published as independent Go modules (with their own go.mod) while living in the same repository tree and connected via replace directives in the root go.mod. A separate ui/ directory contains a full Ember.js frontend. The result is a monorepo with multiple module boundaries — a pattern common among large HashiCorp projects.
Directory map#
vault/ ← root binary entry point (main.go)
├── api/ ← independent Go module: Go client library (github.com/hashicorp/vault/api)
│ ├── auth/ ← auth helper subpackages (approle, aws, etc.)
│ ├── cliconfig/ ← CLI configuration helpers
│ └── tokenhelper/ ← token helper abstraction
├── audit/ ← audit backend implementations (file, socket, syslog)
├── builtin/ ← all built-in plugins compiled into the binary
│ ├── credential/ ← auth methods: approle, aws, cert, github, ldap, okta, radius, token, userpass
│ ├── logical/ ← secret engines: aws, consul, database, nomad, pki, pkiext, rabbitmq, ssh, totp, transit
│ └── plugin/ ← generic plugin backend (delegates to external plugin process)
├── command/ ← CLI command implementations (vault <subcommand>)
│ ├── agent/ ← vault agent end-to-end tests
│ ├── agentproxyshared/ ← shared code between agent and proxy
│ ├── config/ ← HCL config file parsing for agent/proxy
│ ├── healthcheck/ ← health check command logic
│ ├── proxy/ ← vault proxy command
│ ├── server/ ← vault server command and server config parsing
│ └── token/ ← token file helpers
├── helper/ ← internal utility packages (not exported as SDK)
│ ├── builtinplugins/ ← registry: maps plugin names to factory functions
│ ├── fairshare/ ← work queue with fairness scheduling
│ ├── identity/ ← protobuf types for identity entities/groups
│ ├── metricsutil/ ← Prometheus/dogstatsd metrics helpers
│ ├── namespace/ ← namespace context helpers
│ ├── testhelpers/ ← large test helper package for integration tests
│ └── ... (20+ utility packages)
├── http/ ← HTTP handler layer (mux registration, middleware)
│ └── priority/ ← request priority/limiting middleware
├── internal/ ← strictly internal packages (Go convention enforced)
│ └── observability/ ← OTEL tracing helpers
├── internalshared/ ← packages shared between main module and sdk (unusual split)
│ ├── configutil/ ← shared config parsing utilities
│ └── listenerutil/ ← TLS listener configuration helpers
├── limits/ ← request rate and resource limiting
├── physical/ ← storage backend implementations
│ ├── aerospike/ ← Aerospike backend
│ ├── azure/ ← Azure Blob Storage backend
│ ├── cassandra/ ← Cassandra backend
│ ├── consul/ ← Consul KV backend
│ ├── dynamodb/ ← DynamoDB backend
│ ├── etcd/ ← etcd backend
│ ├── gcs/ ← Google Cloud Storage backend
│ ├── postgresql/ ← PostgreSQL backend
│ ├── raft/ ← Integrated Raft (HashiCorp raft) backend — the default
│ ├── s3/ ← AWS S3 backend
│ └── ... (15+ storage backends)
├── plugins/ ← (thin) plugin catalog support
├── sdk/ ← independent Go module: plugin development SDK (github.com/hashicorp/vault/sdk)
│ ├── database/ ← database plugin protocol (dbplugin)
│ ├── framework/ ← high-level framework for writing Vault backends
│ ├── helper/ ← 40+ utility packages for plugin authors
│ ├── logical/ ← core interfaces: Backend, Storage, Request, Response
│ ├── physical/ ← storage interface + file/inmem reference implementations
│ ├── plugin/ ← plugin client/server (go-plugin RPC wrapper)
│ ├── queue/ ← priority queue for credential rotation
│ └── rotation/ ← automated secret rotation helpers
├── serviceregistration/ ← service discovery backends
│ ├── consul/ ← Consul service registration
│ └── kubernetes/ ← Kubernetes service registration
├── shamir/ ← Shamir's Secret Sharing implementation (for unseal)
├── tools/ ← developer tooling (codechecker, semgrep, stubmaker)
├── ui/ ← Ember.js frontend application (separate npm project)
├── vault/ ← core server logic (Core struct, router, token store, policy store…)
│ ├── activity/ ← client activity / billing log
│ ├── cluster/ ← HA cluster coordination
│ ├── diagnose/ ← vault operator diagnose
│ ├── eventbus/ ← internal event pub/sub (for event notifications API)
│ ├── plugincatalog/ ← runtime plugin catalog management
│ ├── quotas/ ← request/rate/lease quotas
│ ├── seal/ ← seal/unseal logic (autounseal, shamir)
│ └── tokens/ ← token store helpers
├── version/ ← version string package
└── website/ ← MDX documentation source (published to developer.hashicorp.com)Entry points#
| File | Binary | Purpose |
|---|---|---|
main.go | vault | Single binary entry point; delegates immediately to command.Run() |
command/main.go | (package, not standalone) | Implements Run() / RunCustom() — CLI dispatcher using hashicorp/cli |
command/server/ | (subcommand) | vault server — starts the Vault server process |
command/agent/ | (subcommand) | vault agent — starts Vault Agent (auto-auth + template rendering) |
command/proxy/ | (subcommand) | vault proxy — starts Vault Proxy (API proxy with caching) |
There is a single compiled binary. All modes (server, agent, proxy, CLI) are subcommands of that binary.
Package organization#
- Internal packages:
vault/(core),helper/,http/,internal/,internalshared/,command/,audit/,physical/,serviceregistration/,builtin/,limits/,shamir/ - Public packages (published as sub-modules):
sdk/— plugin development SDK;sdk/logicaldefinesBackend,Storage,Request,Response;sdk/frameworkprovides a high-level helper for writing backendsapi/— Go client library; intended for both CLI and third-party integration
- Layering:
- Bottom layer:
sdk/logical(interfaces only) +sdk/physical(storage interface) - Implementation layer:
vault/(Core, router, token/policy stores),physical/backends,audit/backends - Plugin layer:
builtin/credential/andbuiltin/logical/implementsdk/logical.Backend - HTTP layer:
http/wrapsvault/Corein an HTTP server - CLI layer:
command/usesapi/client to communicate with the HTTP layer - This is a strict layered architecture: the
sdkmodule has no dependency on the main module; plugins can be developed without access to vault internals.
- Bottom layer:
Build system#
- Build tool: GNU Make (
Makefile) + custom shell scripts (scripts/build.sh) - Key targets:
make dev— builds a development binary to./bin/vaultwithtestonlybuild tagmake bin— builds release binary with UI assets embeddedmake dev-ui— builds dev binary with UI assetsmake test— runs all unit tests across main, sdk, and api packagesmake fmt— runsgofmton all non-generated Go files
- Build tags used:
testonly(enables test-only code paths),ui(embeds web UI),foundationdb(enables CGO + FoundationDB backend),minimal(strips non-core backends) - Docker: Yes, multi-stage — the
Dockerfileuses Alpine as the final stage and acceptsBIN_NAME,PRODUCT_VERSION,TARGETARCHbuild args, pulling pre-built binaries from HashiCorp’s release infrastructure (not building from source inside Docker) - CI: GitHub Actions (
.github/workflows/); Enos framework (enos/) for integration/acceptance testing across cloud environments
Notable structural decisions#
Three Go modules in one repo: The root module (
github.com/hashicorp/vault),sdk/(github.com/hashicorp/vault/sdk), andapi/(github.com/hashicorp/vault/api) are all separate modules connected byreplacedirectives during development. This allowssdkandapito be imported by third-party plugin authors without pulling in the full Vault server and its 300+ dependencies.vault/package shadows the repo root: The most important package isvault/vault/(import pathgithub.com/hashicorp/vault/vault). Naming the core package the same as the project while placing it in a subdirectory is unusual but deliberate — it prevents the core from being the root package, keepingmain.gothin.physical/has 20+ storage backends compiled in: Unlike many projects that rely on external plugins for storage, Vault compiles all storage backends directly into the binary and selects at runtime via config. This avoids deployment complexity at the cost of binary size.internalshared/is an unusual seam: Packages shared between the root module and thesdkmodule (but not meant for external use) live ininternalshared/rather than in either module’sinternal/directory — a pragmatic workaround for Go’sinternal/visibility rules across module boundaries.helper/testhelpers/is a massive test infrastructure package: Rather than scattered test helpers, a large consolidated package athelper/testhelpers/provides cluster creation, unsealing, replication setup, and more. This reflects how deeply integration-tested Vault is — test infrastructure is first-class code.Enterprise/CE split accommodated by build stubs: Files like
command/server/server_stubs_oss.goandvault/logical_system_fields_stubs_oss.gouse theossnaming convention to provide no-op implementations of enterprise features in the community edition, enabling the enterprise branch to swap in real implementations without#ifdef-style conditionals.