Security¶
Target Architecture — Final-State Design
This page describes the final-state security model for the Factory Studio. Authentication via OpenIddict (ConnectSoft.AuthorizationServerTemplate) and the multi-tenant SignalR substrate are implemented today; the role model and per-module authorization below are the designed end state.
The Factory Studio is the human control surface of an autonomous factory, so its security posture is defence-in-depth at the edge: every page, BFF query, command, and real-time stream is authenticated, authorized, tenant-scoped, and audited. The Studio holds no factory secrets and owns no source-of-truth data, but because it is where human authority is exercised (approvals, overrides, installs), its authorization and audit guarantees are first-class.
Authentication¶
Authentication is provided by OpenIddict via ConnectSoft.AuthorizationServerTemplate, the same authorization server the rest of the factory uses.
- OIDC / OAuth 2.1 code flow with PKCE. The Blazor shell authenticates users against the OpenIddict server using the authorization-code flow with PKCE; no credentials ever touch the BFF tier.
- Bearer access tokens. The shell calls
StudioBffand the realtime gateway with short-lived JWT access tokens; refresh tokens are rotated. Tokens carrytenantId,sub(userId), roles, and scopes. - Token validation everywhere. Every
ConnectSoft.Factory.Studio.*service validates the token (issuer, audience, signature, expiry) on every request; the realtime gateway validates the token on SignalR connect and re-validates on group join. - Service-to-service auth. BFF-to-platform calls use the client-credentials flow (or on-behalf-of where user context must flow) so downstream platforms enforce their own authorization rather than trusting the BFF blindly.
- Session continuity. The shell maintains the authenticated session context shared across all microfrontends; sign-out revokes the session and disconnects SignalR.
Authorization (RBAC)¶
Authorization is role-based, tenant-scoped, and enforced at the BFF, never only in the UI. UI hiding is a convenience; the authoritative check happens server-side on every query and command. Each of the 13 UI modules maps to read and act permissions per role.
Module authorization matrix¶
Legend: R = read/view, A = act (commands such as decide, override, install, edit).
| Module | Operator | Architect | Reviewer | Approver | QA | Security Officer | SRE | FinOps | Knowledge Steward | Tenant Admin | Platform Admin | Viewer |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Project Command Center | R | R | R | R | R | R | R | R | R | R | R | R |
| Blueprint Designer | R | R/A | R | R | R | R | – | – | R | R/A | R/A | R |
| Agent Flow Explorer | R/A | R/A | R | R | R | R | R | – | R | R/A | R/A | R |
| Artifact Lineage Browser | R | R | R | R | R | R | – | – | R | R | R | R |
| Knowledge Graph Explorer | R | R | R | R | – | R | – | – | R/A | R | R | R |
| Human Review Center | R | R/A | R/A | R/A | R | R | – | – | – | R/A | R/A | – |
| QA Center | R | R | R | R | R/A | R | – | – | – | R | R/A | R |
| Security Center | R | R | R | R | R | R/A | R | – | – | R | R/A | – |
| DevOps Center | R/A | R | R | R | R | R | R/A | – | – | R | R/A | R |
| Runtime Center | R/A | R | – | – | R | R | R/A | R | – | R | R/A | R |
| Cost Center | R | R | – | – | – | – | R | R/A | – | R/A | R/A | R |
| Marketplace Install Center | R | R/A | – | – | – | R | – | R | – | R/A | R/A | – |
| Admin / Settings | – | – | – | – | – | R | – | – | – | R/A | R/A | – |
- Least privilege. Roles grant only what a function needs;
Vieweris read-only across most modules and excluded from review, security, and admin surfaces. - Override is privileged.
AgentDecisionOverriddenrequiresApproverorPlatform Administratorand an explicit elevated scope, and is always audited (see Workflows). - Project-scoped grants. Roles are assignable per project as well as per tenant, so a Reviewer on one project is not automatically a Reviewer on another.
- Policy checks. Sensitive commands additionally consult Governance, Security & Compliance policy evaluation before execution. This builds on the implemented Security & Access Control module.
Tenant isolation¶
tenantIdis resolved from the access token (never from URL or body) and stamped on every downstream call, store query, Redis cache key, and SignalR group.- BFF read models, dashboard caches, and preview sessions are partitioned by
tenantId; a tenant can never read or be pushed another tenant's data. - The realtime gateway authorizes group membership against the token's
tenantIdon connect and join, so the live stream is isolated exactly like REST. Platform Administrator(ConnectSoft staff) is the only role that can operate cross-tenant, and every cross-tenant access is explicitly audited with elevated scrutiny.
Secret handling¶
- The Studio holds no business secrets at rest and stores no artifact bodies; previews are rendered through expiring sessions over Knowledge artifact memory.
- Service credentials, signing keys, and downstream client secrets are stored in Azure Key Vault and injected at runtime; nothing is committed to source or baked into MFE bundles.
- Browser-delivered MFE bundles contain no secrets and no privileged endpoints — all privileged operations are server-side BFF commands.
- Tokens are short-lived with rotating refresh tokens; SignalR connections re-authorize on reconnect.
- Preview sessions never expose raw storage URIs (e.g. Blob SAS) to the client; the service proxies and redacts.
Audit¶
- Every state-changing action — review decisions, overrides, escalations, saved-view sharing, marketplace installs, admin changes — emits a canonical-envelope event carrying
tenantId,userId(as actor),traceId, andcorrelationId. ReviewDecisionis append-only and immutable, and is mirrored to the Governance audit sink, making the human-in-the-loop fully reconstructable.- Read access to sensitive surfaces (Security Center findings, restricted artifact previews, knowledge-graph restricted nodes) is logged for access auditing.
- Audit records are correlated end to end with the originating factory lifecycle via
traceId, supporting traceability and incident forensics.
Threat model¶
flowchart TB
subgraph Threats["Threats"]
T1["Cross-tenant data access"]
T2["Privilege escalation / unauthorized override"]
T3["Token theft / replay"]
T4["Unauthorized real-time stream access"]
T5["Sensitive artifact / secret exposure"]
T6["Review tampering / repudiation"]
end
subgraph Mitigations["Mitigations"]
M1["tenantId from token on every query, cache key, group"]
M2["Server-side RBAC + Governance policy on every command"]
M3["Short-lived JWT, PKCE, refresh rotation, Key Vault"]
M4["SignalR group authorization on connect + join"]
M5["Expiring preview sessions, redaction, no storage URIs"]
M6["Append-only immutable decisions + envelope audit"]
end
T1 --> M1
T2 --> M2
T3 --> M3
T4 --> M4
T5 --> M5
T6 --> M6
| Threat | Mitigation |
|---|---|
| Cross-tenant data access | Token-derived tenantId enforced on every BFF query, cache key, and SignalR group; isolation tests in CI. |
| Privilege escalation / unauthorized override | Server-side RBAC + Governance policy evaluation on every command; override requires elevated role and audited rationale. |
| Token theft / replay | Short-lived tokens, PKCE, refresh-token rotation, audience/issuer validation, secrets in Key Vault. |
| Unauthorized real-time access | SignalR authorization on connect and group join; events filtered to authorized groups only. |
| Sensitive artifact / secret exposure | Expiring, classification-checked preview sessions with server-side redaction; no secrets in MFE bundles. |
| Review tampering / repudiation | Append-only immutable ReviewDecision; every action emits an audited envelope event mirrored to Governance. |