Open-Source Wikis

/

Vault

/

Systems

/

Audit

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.go

Key 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_path is 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.go is the in-process glue between the audit table and the broker.
  • The broker is wired into Core.HandleRequest for both pre- and post-call logging.
  • Logs to a separate file from server.log to 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.Backend and register a factory in command/commands.go's auditBackends.
  • 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.

Audit – Vault wiki | Factory