Implements 064-auth-structure (Auth Structure v1.0): Adds platform_users + PlatformUser identity (factory + seeder) for platform operators Introduces platform auth guard/provider in auth.php Adds a dedicated Filament v5 System panel at system using guard platform (custom login + dashboard) Enforces strict cross-scope isolation between /admin and system (deny-as-404) Adds platform capability gating (platform.access_system_panel, platform.use_break_glass) + gates in AuthServiceProvider Implements audited break-glass mode (enter/exit/expire), banner via render hook, feature flag + TTL config Removes legacy users.is_platform_superadmin runtime usage and adds an architecture test to prevent regressions Updates tenant membership pivot usage where needed (tenant_memberships) Testing: vendor/bin/sail artisan test --compact tests/Feature/Auth (28 passed) vendor/bin/sail bin pint --dirty Notes: Filament v5 / Livewire v4 compatible. Panel providers registered in providers.php. Destructive actions use ->action(...) + ->requiresConfirmation() where applicable. Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box> Reviewed-on: #77
101 lines
9.2 KiB
Markdown
101 lines
9.2 KiB
Markdown
# 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%. |