Multi-Tenant Same-Key End-to-End Flow Sequences

Audience: engineers working on Authority, Router/Gateway, Platform, Scanner, Graph, or the Web Console who need the canonical tenant-selection sequences when one identity (the same API key or user) is assigned to multiple tenants. Companion: the per-service implementation contract is the Multi-Tenant Same-Key Service Impact Ledger; the design decision is ADR-002 — Multi-tenant same-API-key selection.

The sequence diagrams below capture sign-in, tenant switching, request propagation, and failure handling for the same-key multi-tenant model. They are the behavioral baseline that the affected services must satisfy.

1) Sign-in to Tenant Mapping

sequenceDiagram
    autonumber
    participant User
    participant Web as Web Console
    participant Auth as Authority
    participant Gw as Router/Gateway
    participant Svc as Tenant-scoped API

    User->>Web: Sign in
    Web->>Auth: /connect/authorize + PKCE
    Auth-->>Web: auth code
    Web->>Auth: /connect/token (client credentials or password grant, tenant=)
    Auth->>Auth: Resolve selected tenant from tenant + tenants metadata
    Auth-->>Web: Access token (stellaops:tenant + optional stellaops:allowed_tenants)
    Web->>Auth: /console/tenants
    Auth-->>Web: { tenants[], selectedTenant }
    Web->>Web: Hydrate ConsoleSessionStore + AuthSessionStore + PlatformContext
    Web->>Gw: API request + canonical tenant header
    Gw->>Svc: Forward resolved tenant context
    Svc-->>Web: Tenant-scoped response

Deterministic selection rule:

2) Header Selector Tenant Switch

sequenceDiagram
    autonumber
    participant User
    participant Topbar as Header Tenant Selector
    participant Session as ConsoleSessionService
    participant Auth as Authority
    participant Stores as Session/Context Stores
    participant APIs as Platform/Scanner/Graph APIs

    User->>Topbar: Select tenant "tenant-bravo"
    Topbar->>Session: switchTenant("tenant-bravo")
    Session->>Stores: Optimistic selectedTenant update
    Session->>Auth: /console/tenants (tenant header=tenant-bravo)
    Auth-->>Session: allowed tenants + selectedTenant
    Session->>Auth: /console/profile + /console/token/introspect
    Auth-->>Session: profile/token introspection for selected tenant
    Session->>Stores: Commit tenant to Console/Auth/Platform/TenantActivation stores
    Session->>APIs: Trigger context reload for tenant-scoped data
    APIs-->>Topbar: Refreshed tenant-scoped responses

Error recovery path:

3) API Request Propagation Through Gateway

sequenceDiagram
    autonumber
    participant UI as Web API Client
    participant I as Tenant/Context Interceptors
    participant Gw as Router/Gateway
    participant Backend as Platform/Scanner/Graph

    UI->>I: Outgoing request
    I->>I: Resolve active tenant from canonical runtime state
    I-->>UI: Add canonical header X-StellaOps-TenantId (+ compat aliases)
    UI->>Gw: Request with tenant headers + token
    Gw->>Gw: Strip caller-supplied identity headers, derive tenant from validated claims, rewrite canonical headers
    Gw->>Backend: Forward tenant-scoped request
    Backend->>Backend: Resolve tenant context + enforce tenant ownership
    Backend-->>UI: Deterministic success/failure payload

Cache/store invalidation points after tenant switch:

4) Failure Sequences

Missing tenant context

Tenant mismatch

Insufficient scope