# Feature Specification: Auth Structure v1.0: Panel & Identity Separation **Feature Branch**: `064-auth-structure` **Created**: Tuesday, January 27, 2026 **Status**: Draft **Input**: User description: "Spec 064 — Auth Structure v1.0 Panel & Identity Separation..." ## User Scenarios & Testing *(mandatory)* ### User Story 1 - Tenant Admin Access (Priority: P1) A Tenant Administrator needs to securely access their organization's resources. They will log in to the `/admin` panel using their existing company credentials via Microsoft Entra ID (OIDC). The system must ensure they only see their tenant's data and have no access to platform-level controls. **Why this priority**: This is the primary user flow for the application's customers. It must be secure, seamless, and strictly isolated from the platform operations. **Independent Test**: Can be tested by attempting to log in with a valid Entra ID account, verifying successful access to `/admin/t/{tenant}`, and confirming that `/system` returns a 404 error. This delivers the core value of tenant administration. **Acceptance Scenarios**: 1. **Given** a user is not authenticated, **When** they navigate to `/admin/login`, **Then** they are presented only with a "Sign in with Microsoft" option. 2. **Given** a valid Tenant Admin uses the Microsoft login, **When** they successfully authenticate, **Then** they are redirected to their tenant-specific dashboard within the `/admin` path. 3. **Given** an authenticated Tenant Admin, **When** they attempt to access any `/system/*` URL, **Then** they receive a 404 Not Found response. --- ### User Story 2 - Platform Operator Access (Priority: P1) A Platform Operator needs to manage the overall application and perform system-level tasks. They will log in to the `/system` panel using a locally stored username and password. Their access is separate from any tenant's identity system. **Why this priority**: This flow is critical for system maintenance, operations, and emergency recovery. It guarantees that platform administrators can always access the system, even if a tenant's Entra ID is unavailable. **Independent Test**: Can be tested by logging in with a seeded `platform_user` account, verifying access to the `/system` dashboard, and confirming that tenant-scoped admin routes (`/admin/t/*`) return a 404 error. **Acceptance Scenarios**: 1. **Given** a user is not authenticated, **When** they navigate to `/system/login`, **Then** they are presented with an email and password login form. 2. **Given** a valid Platform Operator provides correct credentials, **When** they log in, **Then** they are redirected to the `/system` dashboard. 3. **Given** an authenticated Platform Operator, **When** they attempt to access a tenant-scoped URL like `/admin/t/{tenant}/*`, **Then** they receive a 404 Not Found response. --- ### User Story 3 - Break-glass Emergency Recovery (Priority: P2) A Platform Operator with the appropriate permissions needs to perform an emergency recovery action on a tenant's behalf. They must enter a temporary, audited "break-glass" mode from within the `/system` panel to gain the necessary (but limited and logged) privileges. **Why this priority**: Provides a crucial, secure mechanism for disaster recovery and support, while ensuring such powerful access is explicitly enabled, temporary, and fully audited. It's a safety net, not a primary workflow. **Independent Test**: Can be tested by enabling the feature flag, having a privileged Platform Operator start the break-glass session, verifying the persistent banner appears, performing a recovery action, and then exiting the mode. The audit log must reflect all state changes. **Acceptance Scenarios**: 1. **Given** the `BREAK_GLASS_ENABLED` flag is `true` and a Platform Operator has the `platform.use_break_glass` capability, **When** they initiate the "Enter break-glass mode" action, **Then** a persistent banner indicating "Recovery mode active" is displayed on all `/system` pages. 2. **Given** a Platform Operator is in break-glass mode, **When** the configured TTL expires, **Then** the break-glass session is automatically terminated, the banner is removed, and an "expired" event is logged. 3. **Given** a Platform Operator is in break-glass mode, **When** they click the "Exit break-glass" button, **Then** the session is immediately terminated, the banner is removed, and an "exit" event is logged. 4. **Given** the `BREAK_GLASS_ENABLED` flag is `false`, **Then** no option to enter break-glass mode is visible in the UI. ### Edge Cases - What happens if a user's session expires while in break-glass mode? The break-glass state should be cleared along with the regular session. - How does the system handle a login attempt for a `platform_user` whose account is marked as inactive? The login should fail with a generic "invalid credentials" message. - What if a backfill migration runs for a `users.is_platform_superadmin` who already has a `platform_user` account? It should idempotently add the capabilities without creating a duplicate user. ## Requirements *(mandatory)* **Constitution alignment (required):** This feature introduces significant changes to authentication and authorization. - **Graph Calls**: No new direct Graph calls are specified for this core auth structure, but the `/admin` panel relies on Entra OIDC (from feature 063). - **Safety Gates**: The "break-glass" feature is a critical safety gate itself. It is gated by a feature flag (`BREAK_GLASS_ENABLED`), requires explicit user action with confirmation, is time-limited (TTL), and produces a detailed audit trail. Tenant recovery actions within this mode are also explicitly audited. - **Tenant Isolation**: This is a primary goal. The spec enforces strict separation via different authentication scopes and routing rules that return 404 for cross-scope access attempts, preventing information leakage. - **Run Observability**: While auth handshakes don't create `OperationRun`s (OPS-EX-AUTH-001), security-relevant actions MUST create detailed `AuditLog` entries. This includes platform login attempts (success and failure) and break-glass lifecycle events (enter, exit, expire), including actor, action, outcome, and timestamp. - **Badge Alignment**: Not applicable. ### Functional Requirements - **FR-001**: The system MUST provide two separate admin experiences: `/admin` for Tenants and `/system` for Platform Operators. - **FR-002**: The `/admin` experience MUST authenticate tenant admins via Microsoft Entra ID (OIDC). - **FR-003**: The `/system` experience MUST authenticate platform operators via locally managed credentials stored separately from tenant identities. - **FR-004**: The system MUST implement a "break-glass" mode for privileged platform users, which is disabled by default via a `BREAK_GLASS_ENABLED` environment variable. - **FR-005**: When active, break-glass mode MUST display a persistent banner on all `/system` pages and expire automatically after a configurable TTL. All state transitions (start, exit, expiry) MUST be audited. - **FR-006**: The `users.is_platform_superadmin` database column MUST be deprecated; no new code may use it for authorization checks. - **FR-007**: An authenticated tenant session attempting to access any `/system/*` route MUST receive a 404 Not Found response. - **FR-008**: An authenticated platform session attempting to access any tenant-scoped `/admin/t/{tenant}/*` route MUST receive a 404 Not Found response. - **FR-009**: The system MUST provide a capability-based authorization system for platform users (e.g., `platform.access_system_panel`, `platform.use_break_glass`). - **FR-010**: The login page at `/admin/login` MUST NOT contain password fields or links related to local auth or break-glass. - **FR-011**: All platform login attempts (success and failure) and break-glass lifecycle events MUST be recorded in an audit log. ### Key Entities - **PlatformUser**: Represents a platform operator with local credentials. Attributes include name, email, hashed password, and a list of capabilities. It is distinct from the tenant user identity. - **Break-glass Session**: A temporary, elevated session state for a PlatformUser, not a database entity. It is managed via session state that tracks the expiry time, the initiating actor, and an operator-provided reason. ## Success Criteria *(mandatory)* ### Measurable Outcomes - **SC-001**: 100% of authentication attempts to the `/admin` panel are routed through the Entra OIDC flow. - **SC-002**: 100% of authentication attempts to the `/system` panel are routed through the local `platform_users` provider. - **SC-003**: 0% of authenticated users from one panel can successfully access scoped resource pages in the other panel (verified by 404 responses). - **SC-004**: When break-glass mode is activated, a persistent visual indicator is present on 100% of `/system` pages until the session is terminated (manually or by TTL). - **SC-005**: All break-glass session activations, expirations, and manual exits are logged, with 100% of events recorded in the audit trail. - **SC-006**: Code coverage for the new authentication guards, middleware, and platform authorization gates is at or above 80%. - **SC-006**: Automated test coverage for the authentication separation and break-glass flows is at or above 80%.