# Feature Specification: RBAC Troubleshooting & Tenant UI Bugfix Pack v1 **Feature Branch**: `067-rbac-troubleshooting` **Created**: 2026-01-31 **Status**: Draft **Input**: RBAC troubleshooting + tenant admin UI bugfix pack focused on the tenant-plane admin experience (`/admin`). ## User Scenarios & Testing *(mandatory)* ### User Story 1 - Permission-safe tenant UI interactions (Priority: P1) A tenant member with read-only permissions can browse tenant pages and menus without being sent to error pages for normal UI clicks. **Why this priority**: Eliminates confusing UX and reduces support load; also prevents “permission leak” regressions in high-risk actions. **Independent Test**: As a read-only member, verify restricted actions are visible-but-disabled with an explanatory tooltip and cannot be executed. **Acceptance Scenarios**: 1. **Given** a user is a member of a tenant but lacks tenant management capability, **When** they view tenant lists and pages, **Then** management actions (e.g. Edit, Deactivate) are disabled and show an explanatory tooltip. 2. **Given** a user is a member but lacks tenant management capability, **When** they attempt to execute a blocked mutation (direct request / forced execution), **Then** the server denies it. --- ### User Story 2 - Archived tenant remains viewable for entitled members (Priority: P1) A tenant member who is entitled to view a tenant can still access the tenant view even if the tenant is archived, and the UI clearly indicates status. **Why this priority**: Prevents accidental “false 404” for legitimate members; enables safe lifecycle operations like restore. **Independent Test**: Mark a tenant archived, ensure a viewing member can load it and sees an “Archived” banner; ensure non-members still receive 404. **Acceptance Scenarios**: 1. **Given** a tenant is archived and a user is a member with tenant view capability, **When** they navigate to the tenant view, **Then** the page loads and shows an “Archived” status banner. 2. **Given** a tenant is archived and a user is not a member, **When** they navigate to the tenant scope URL, **Then** they receive a 404 (deny-as-not-found). --- ### User Story 3 - Diagnose & repair tenant membership invariants (Priority: P2) An authorized tenant owner/manager can identify and fix membership integrity issues (missing owner, duplicates) via a dedicated troubleshooting screen. **Why this priority**: Provides a recovery path for real-world “sharp edges” without requiring direct database intervention. **Independent Test**: Seed broken states (0 owners, duplicate memberships), confirm diagnostics flag them and repair actions resolve them. **Acceptance Scenarios**: 1. **Given** a tenant has no owners, **When** an authorized user opens diagnostics, **Then** the issue is surfaced and a repair action can promote a member to owner. 2. **Given** a tenant has duplicate memberships for the same user, **When** an authorized user runs “merge duplicates”, **Then** duplicates are removed and exactly one membership remains. ### Edge Cases - A tenant member without management capability attempts to execute a blocked action via a forged request. - A non-member attempts to access a tenant-scoped page (must be deny-as-not-found). - Tenant is archived: view allowed for entitled members; lifecycle actions are status-appropriate. - Tenant has 0 owners; tenant has 1 owner and an action would demote/remove the last owner. - Membership duplicates exist and are resolved; ensure resulting owner count remains valid. - A tenant has an external GUID identifier; ensure no internal lookups treat that GUID as the internal tenant primary key. ## Requirements *(mandatory)* **Constitution alignment (required):** If this feature introduces any Microsoft Graph calls, any write/change behavior, or any long-running/queued/scheduled work, the spec MUST describe contract registry updates, safety gates (preview/confirmation/audit), tenant isolation, run observability (operation run record: type/identity/visibility), and tests. If security-relevant DB-only actions intentionally skip an operation run record, the spec MUST describe audit log entries. **Constitution alignment (RBAC-UX):** If this feature introduces or changes authorization behavior, the spec MUST: - state which authorization plane(s) are involved (tenant `/admin/t/{tenant}` vs platform `/system`), - ensure any cross-plane access is deny-as-not-found (404), - explicitly define 404 vs 403 semantics: - non-member / not entitled to tenant scope → 404 (deny-as-not-found) - member but missing capability → 403 - describe how authorization is enforced server-side (Gates/Policies) for every mutation/operation-start/credential change, - reference the canonical capability registry (no raw capability strings; no role-string checks in feature code), - ensure global search is tenant-scoped and non-member-safe (no hints; inaccessible results treated as 404 semantics), - ensure destructive-like actions require an explicit confirmation step, - include at least one positive and one negative authorization test, and note any RBAC regression tests added/updated. **Constitution alignment (OPS-EX-AUTH-001):** OIDC/SAML login handshakes may perform synchronous outbound HTTP (e.g., token exchange) on `/auth/*` endpoints without an operation run record. This MUST NOT be used for Monitoring/Operations pages. **Constitution alignment (BADGE-001):** If this feature changes status-like badges (status/outcome/severity/risk/availability/boolean), the spec MUST describe how badge semantics stay centralized (no ad-hoc mappings) and which tests cover any new/changed values. ### Functional Requirements - **FR-001 (Restore action icon)**: The tenant list row menu MUST display a consistent icon for the Restore action. - **FR-002 (Readonly edit UX)**: For a tenant member lacking tenant management capability, the UI MUST present Edit as disabled with an explanatory tooltip and MUST avoid normal-click navigation leading to an error page. - **FR-003 (Readonly cannot deactivate)**: Deactivate MUST be treated as a protected mutation and MUST NOT be executable by a tenant member lacking tenant management capability. - **FR-004 (Archived tenant access)**: An entitled tenant member (tenant view capability) MUST be able to open archived tenants. A non-member MUST receive a 404 for tenant scope URLs. - **FR-005 (Owner invariant)**: The system MUST prevent removing/demoting the last remaining tenant owner and MUST surface “missing owner” situations in diagnostics. - **FR-006 (Membership integrity)**: The system MUST prevent duplicate memberships per (tenant, user). Diagnostics MUST identify duplicates and provide a safe repair flow for authorized users. - **FR-007 (GUID vs internal ID)**: The system MUST treat external tenant identifiers (GUIDs) as external-only identifiers and MUST NOT use them where an internal tenant primary key is required. - **FR-008 (Diagnostics access + safety)**: Diagnostics MUST not expose cross-tenant data to non-members. Repair actions MUST be permission-gated and MUST record an auditable trail. #### Authorization & Error Semantics (explicit) - Tenant-scope URLs: non-member / not entitled MUST be deny-as-not-found (404). - Member but missing capability: server-side MUST deny execution (403). - UI behavior: member-without-capability SHOULD see actions visible-but-disabled with tooltip to prevent normal-click 403 pages. #### Out of Scope - No new “Workspace” model in this spec. - No platform-plane (`/system`) expansion. - No outbound integration calls are introduced as part of diagnostics/repairs. #### Assumptions - “Archived” is treated as an archived/lifecycle state that remains viewable to entitled members. - Deactivate (archive) uses the existing tenant lifecycle capability `Capabilities::TENANT_DELETE`. ### Key Entities *(include if feature involves data)* - **Tenant**: The internal customer/workspace entity users are members of; has an internal primary key and an external identifier. - **Tenant Membership**: Links a user to a tenant with one or more capability grants or derived entitlements. - **Capability / Entitlement**: A named permission used to determine visibility/execution of actions within a tenant scope. - **Diagnostics Finding**: A detected issue such as “missing owner”, “duplicate membership”, or “identifier misuse risk”. - **Repair Action**: A controlled, permission-gated remediation step that fixes a finding and records an audit entry. ## Success Criteria *(mandatory)* ### Measurable Outcomes - **SC-001**: Read-only members can navigate all tenant UI flows covered by automated tests without encountering an error page during normal click paths. - **SC-002**: Protected tenant mutations (e.g., deactivate) have 0 successful executions by users lacking the required capability across automated tests. - **SC-003**: Archived tenant access works as defined: entitled members can view; non-members get 404, verified by automated tests. - **SC-004**: Membership integrity can be restored via UI-only repair actions for seeded broken states, verified by automated tests.