hashicorp/vault
Audit
Every request and response in Vault is fed to the audit broker, which fans it out to one or more configured audit devices (file, socket, syslog). If no audit device is configured, Vault still works; if at least one is configured but unreachable, Vault refuses to handle the request. Source: audit/ (24 files).
Purpose
- Provide a tamper-evident log of every API call.
- HMAC sensitive fields so audit logs themselves don't leak secrets.
- Fan-out to multiple destinations with consistent serialization.
- Be loud and fail-closed when an audit destination misbehaves.
Directory layout
audit/
├── broker.go # Audit broker, fan-out logic
├── broker_ce.go # CE stub
├── backend.go # Backend interface
├── backend_ce.go # CE stub
├── backend_config.go # Per-device options
├── backend_file.go # file device
├── backend_noop.go # for tests
├── backend_socket.go # tcp/unix socket device
├── backend_syslog.go # syslog device
├── entry_filter.go # event filtering
├── entry_formatter.go # serialize request/response into audit JSON
├── entry_formatter_ce.go # CE stub
├── entry_formatter_config.go
├── event.go # audit event types
├── hashstructure.go # HMAC sensitive fields
├── headers.go # configurable header allow/deny
├── nodes.go # eventlogger pipeline node integration
├── options.go
├── path_error.go
├── sink_metric_labeler.go, sink_metric_timer.go, types.go
└── errors.goKey abstractions
| Symbol | File | Description |
|---|---|---|
Broker |
audit/broker.go |
The fan-out broker. Owns one eventlogger pipeline per device. |
Backend |
audit/backend.go |
Per-device interface (LogRequest, LogResponse, Salt). |
EntryFormatter |
audit/entry_formatter.go (21k lines) |
Serializes a request/response into the JSON-on-disk format. |
EntryFilter |
audit/entry_filter.go |
Selects which events to log per device. |
Headers |
audit/headers.go |
The configurable header HMAC list (sys/config/auditing/request-headers). |
HashStructure |
audit/hashstructure.go |
Deep walk of request/response that HMACs sensitive fields. |
How an audit event flows
sequenceDiagram
participant Core as vault.Core
participant Br as audit.Broker
participant F as EntryFormatter
participant H as HMAC salt
participant D as audit device(s)
Core->>Br: LogRequest(req)
Br->>F: build request entry
F->>H: HMAC token, sensitive fields
F-->>Br: JSON entry
Br->>D: write to every active device
Note over Br,D: All devices must succeed.<br/>If any fails, request is rejected.The same flow happens after the response is built (LogResponse). Failures are logged at error level, the request fails with a ErrInternalError, and the operator is expected to investigate immediately.
HMAC of sensitive fields
hashstructure.go walks the request/response and replaces fields like data.password, auth.client_token, and any field listed in the mount's audit_non_hmac_request_keys/audit_non_hmac_response_keys tunables with hmac-sha256:<digest>. The HMAC key is per-device, generated on first start and stored in the audit table. This means audit logs are pseudonymous and you cannot reverse them, but you can correlate two events that mention the same value.
Built-in devices
file: append-only newline-delimited JSON. Rotation is the operator's job (e.g. logrotate).file_pathis the only required option.socket: writes to a TCP or Unix socket. Useful for piping to a remote syslog or aggregator.syslog: classic syslog, configurable facility/tag.
External audit backends are uncommon — most operators use file + socket and let downstream systems do the rest.
Filtering
audit/entry_filter.go supports per-device filters (e.g. only audit operations on secret/*). Filters are evaluated against the audit event before serialization, so a noisy mount doesn't waste device bandwidth.
Headers
headers.go controls which incoming HTTP headers are recorded in audit, and which of those are HMAC'd. The list is operator-configurable via sys/config/auditing/request-headers. By default a small allow-list is recorded.
Integration points
- Mounted via
vault audit enable …;vault/audit.gois the in-process glue between the audit table and the broker. - The broker is wired into
Core.HandleRequestfor both pre- and post-call logging. - Logs to a separate file from
server.logto keep operator and audit concerns distinct. helper/identity/integrates with audit so entity-level metadata is logged when present.
Entry points for modification
- Add a new audit device: implement
audit.Backendand register a factory incommand/commands.go'sauditBackends. - Tweak HMAC behavior for a new sensitive field: extend
hashstructure.go. - Add a per-device filter shape:
audit/entry_filter.go.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.