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.goKey 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-deleteauth/token-create,auth/token-revokepki/issue,pki/revokedatabase/credential-rotatemount-create,mount-deleteaudit/...(filtered byaudit/entry_filter.go)
Plugins are encouraged to publish their own events with sensible namespacing.
Integration points
Core.eventsis constructed invault/core.goand wired intorequest_handling.go.- Plugins receive a handle via
sdk/logical.SystemView.SendEvent. - WebSocket upgrade lives in
http/handler.gounder theevents/subscriberoute. - 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.SendInternalorsystem.SendEvent. - Add a new metadata field: extend
event.proto, regenerate, updateFilter. - 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.