Open-Source Wikis

/

Vault

/

Systems

/

Event bus

hashicorp/vault

Event bus

The event bus is Vault's in-process pub/sub system. It routes notifications about lifecycle events (mount changes, lease expirations, KV updates, audit events, custom plugin events) to internal subscribers and to API clients via events subscribe. Source: vault/eventbus/ (4 files, ~80k lines).

Purpose

  • Provide a typed, namespaced channel for components to publish notifications without coupling.
  • Surface those events to clients over WebSocket via vault events subscribe.
  • Apply filtering so subscribers only see events they're allowed to see.

Directory layout

vault/eventbus/
├── bus.go               # Bus type, publish, subscribe, fan-out
├── bus_test.go
├── filter.go            # Server-side filtering
└── filter_test.go

Key abstractions

Symbol File Description
Bus vault/eventbus/bus.go The bus instance held by Core.events.
EventReceived sdk/logical/event.proto (event.pb.go) The protobuf-defined event type with namespace, mount, plugin, type, ID, payload.
Bus.Subscribe vault/eventbus/bus.go Returns a channel of events filtered by predicate.
Bus.SendInternal / SendEvent vault/eventbus/bus.go Publish an event from internal code or from a plugin's gRPC stream.
Filter vault/eventbus/filter.go bexpr-based predicate compiler used to match events to subscriptions.

How it works

graph LR
    Plugin[Backend plugin] -->|grpc_events.go SendEvent| Bus[Bus]
    Internal[Internal subsystems<br/>tokens, mounts, audit] -->|SendInternal| Bus
    Bus -->|Subscribe filter| WS[WebSocket subscriber]
    Bus --> Audit[Audit pipeline]
    Bus --> Replication[Replication WAL writer]

Plugins emit events through sdk/plugin/grpc_events.go; they arrive at the Bus from the gRPC server side. Internal subsystems publish via direct method calls.

Filtering

vault/eventbus/filter.go uses hashicorp/go-bexpr to compile predicates like:

event_type == "kv-v2/data-write" and namespace_path == "team/secrets"

Predicates run against the event's metadata (namespace_path, mount_path, plugin, event_type, entity_id). Subscribers attach a predicate when they subscribe; only matching events flow through.

Subscriptions API

vault events subscribe '<event-type-pattern>' opens a long-running WebSocket request that the server upgrades and binds to a Bus subscription. The CLI side is in command/events.go. The HTTP side is wired in http/handler.go and gated behind the subscribe capability.

Authorization: the policy must grant subscribe on the path the event lives under, mirroring the read-side permission model.

Built-in event types

A non-exhaustive list of types Vault publishes (search for event.WithMetadata calls):

  • kv-v2/data-write, kv-v2/data-delete, kv-v2/metadata-delete
  • auth/token-create, auth/token-revoke
  • pki/issue, pki/revoke
  • database/credential-rotate
  • mount-create, mount-delete
  • audit/... (filtered by audit/entry_filter.go)

Plugins are encouraged to publish their own events with sensible namespacing.

Integration points

  • Core.events is constructed in vault/core.go and wired into request_handling.go.
  • Plugins receive a handle via sdk/logical.SystemView.SendEvent.
  • WebSocket upgrade lives in http/handler.go under the events/subscribe route.
  • Replication uses event publish hooks to mark replicated state.

Entry points for modification

  • Add a new event type: pick a stable string in your code, document it, emit via core.events.SendInternal or system.SendEvent.
  • Add a new metadata field: extend event.proto, regenerate, update Filter.
  • New filtering operator: extend the bexpr config in filter.go.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Event bus – Vault wiki | Factory