Open-Source Wikis

/

Bitwarden Server

/

Apps

/

Events

bitwarden/server

Events

Active contributors: Dirt (Data Insights & Reporting) team.

Purpose

src/Events/ is a tiny ASP.NET Core service that accepts batches of audit events from authenticated clients and pushes them onto an Azure Storage queue (or Azure Service Bus / RabbitMQ in dev) for later persistence by EventsProcessor. The split exists so that the chatty event-write path doesn't load the same connection pool as the API.

Directory layout

src/Events/
├── Program.cs / Startup.cs
├── Controllers/
│   ├── CollectController.cs   # POST /collect, accepts EventModel[]
│   └── InfoController.cs      # /alive, /version
├── Models/                    # Request DTOs
├── appsettings.{Development,Production,QA,SelfHosted}.json
└── Dockerfile / build.sh / entrypoint.sh

Key abstractions

Type Path Description
Startup src/Events/Startup.cs Configures MVC + Bearer JWT auth scoped to Policies.Application, plus the queue / Service Bus event writer.
CollectController src/Events/Controllers/CollectController.cs POSTs from clients land here; they must include a JWT with the api scope. The controller reads ICurrentContext to attribute the events.
IEventWriteService (resolved at runtime) src/Core/Services/Implementations/AzureQueueEventWriteService.cs, RepositoryEventWriteService.cs, RabbitMqEventWriteService.cs, ... Each implementation persists to a different sink. The Events host typically resolves to the queue writer; EventsProcessor resolves to the repository writer.

How it works

sequenceDiagram
    participant Client
    participant Events
    participant Queue as Azure Queue / Service Bus / RabbitMQ
    participant EP as EventsProcessor
    participant DB

    Client->>Events: POST /collect (Bearer JWT, [{type, cipherId, date,...}])
    Events->>Events: AuthZ Policies.Application
    Events->>Queue: IEventWriteService.CreateManyAsync
    Events-->>Client: 200 Accepted

    EP->>Queue: Dequeue batch
    EP->>DB: Insert into Event table / Cosmos / Azure Table Storage

Integration points

  • Identity — Bearer JWT validation. Only legitimate clients can post events.
  • Queue / BusglobalSettings.Events.ConnectionString selects which writer is used. Self-hosted defaults to the local repository writer (single-process write to SQL).
  • EventsProcessor — the consumer side (see events-processor).
  • Audit logs — surfaced in the Admin Console UI via LogsController and the Public/EventsController org public API.

Why split the write path?

  • Clients post events frequently (every successful sync logs a User_LoggedIn and similar). Putting that on the same hot path as cipher CRUD made the API slow under load.
  • The queue allows replay if EventsProcessor falls behind.
  • It also lets self-host write straight to SQL while cloud uses an event-streaming pipeline.

Entry points for modification

  • New event type → add to EventType (src/Core/Enums/EventType.cs) and use IEventService.LogXxxEventAsync from API code. The Events host doesn't need changes.
  • New ingest sink → implement IEventWriteService and register it conditionally in Startup.ConfigureServices.
  • Different auth policy for the collect endpoint → adjust the Policies.Application reference in CollectController (rare).

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

Events – Bitwarden Server wiki | Factory