Skip to content

Multitenancy — sequences

Sequence diagrams reference ADR-0100 for header/claim names.

HTTP (ASP.NET Core)

sequenceDiagram
  participant Client
  participant Gateway as ApiGatewayTemplate
  participant Mid as SaasTenantMiddleware
  participant Jwt as JwtBearerHandler
  participant App as Controller
  Client->>Gateway: Authorization Bearer
  Gateway->>Gateway: Validate token
  Gateway->>Gateway: Resolve tid to X-Tenant-Id
  Gateway->>Mid: Forward request
  Jwt->>Mid: Populate User with tid
  Mid->>Mid: ITenantResolver pipeline
  Mid->>App: ITenantContext set
  App->>App: NHibernate EnableFilter
Hold "Alt" / "Option" to enable pan & zoom

gRPC (server)

sequenceDiagram
  participant Peer
  participant Interceptor as SaasGrpcServerInterceptor
  participant Svc as GrpcService
  Peer->>Interceptor: Call with metadata tenant-id
  Interceptor->>Interceptor: Validate vs trust policy
  Interceptor->>Svc: Ambient ITenantContext
Hold "Alt" / "Option" to enable pan & zoom

MassTransit consumer

sequenceDiagram
  participant Bus
  participant Filter as SaasConsumeFilter
  participant Consumer
  Bus->>Filter: Consume envelope
  Filter->>Filter: Read tenant-id header
  Filter->>Consumer: MutableTenantContext scoped via DI
Hold "Alt" / "Option" to enable pan & zoom

Implementation note: TenantConsumeContextFilter resolves MutableTenantContext from IServiceScope / IServiceProvider on ConsumeContext. Consumer endpoints must register MutableTenantContext scoped per message — otherwise the filter no-ops.

Orleans grain

sequenceDiagram
  participant Client
  participant Grain as TenantScopedGrain
  Client->>Grain: Invoke with composite key
  Note over Grain: Key format tenantId|aggregateId
Hold "Alt" / "Option" to enable pan & zoom

Outbound publish (outbox)

sequenceDiagram
  participant App
  participant Outbox
  participant Bus
  App->>Outbox: Persist with tenant-id
  Outbox->>Bus: Publish with tenant-id header
Hold "Alt" / "Option" to enable pan & zoom