wip: doctor/cli/docs/api to vector db consolidation; api hardening for descriptions, tenant, and scopes; migrations and conversions of all DALs to EF v10
This commit is contained in:
106
docs/technical/architecture/multi-tenant-flow-sequences.md
Normal file
106
docs/technical/architecture/multi-tenant-flow-sequences.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# Multi-Tenant Same-Key End-to-End Flow Sequences
|
||||
|
||||
Date: 2026-02-22
|
||||
Source sprint: `SPRINT_20260222_053_DOCS_multi_tenant_same_api_key_contract_baseline.md`
|
||||
Related ADR: `docs/architecture/decisions/ADR-002-multi-tenant-same-api-key-selection.md`
|
||||
|
||||
## 1) Sign-in to Tenant Mapping
|
||||
|
||||
```mermaid
|
||||
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=<optional>)
|
||||
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:
|
||||
- If `tenant` parameter is present at token request time, it must be in assigned tenant set.
|
||||
- If no parameter and only one assignment/default exists, use that selected tenant.
|
||||
- If ambiguous (multi-assigned and no default/request), reject.
|
||||
|
||||
## 2) Header Selector Tenant Switch
|
||||
|
||||
```mermaid
|
||||
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:
|
||||
- On switch failure (`403`, `tenant_conflict`, session expiry), restore previous tenant in all stores.
|
||||
- Attempt context reload for previous tenant.
|
||||
- Surface deterministic error in tenant panel with retry action.
|
||||
|
||||
## 3) API Request Propagation Through Gateway
|
||||
|
||||
```mermaid
|
||||
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-Tenant (+ 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:
|
||||
- Console session context cache.
|
||||
- Tenant-scoped page stores (Platform/Scanner/Graph read models).
|
||||
- URL context synchronization where tenant is persisted as global context.
|
||||
|
||||
## 4) Failure Sequences
|
||||
|
||||
### Missing tenant context
|
||||
- Expected result: deterministic `400`/`401`/`403` based on service policy and auth stage.
|
||||
- UI behavior: keep prior selection if available; show recoverable error panel.
|
||||
|
||||
### Tenant mismatch
|
||||
- Trigger: claim tenant != header/request tenant.
|
||||
- Expected result: reject with deterministic conflict error (for example `tenant_conflict` or `tenant_forbidden`).
|
||||
- Audit/telemetry: record attempted tenant override + resolved tenant.
|
||||
|
||||
### Insufficient scope
|
||||
- Trigger: token lacks required policy scope for requested endpoint.
|
||||
- Expected result: deterministic `403` with scope policy failure context.
|
||||
- UI behavior: no tenant mutation; show access-denied state.
|
||||
|
||||
Reference in New Issue
Block a user