# Feature Specification: Enterprise Access Boundary & Support Access Governance v1

**Feature Branch**: `276-support-access-governance`  
**Created**: 2026-05-05  
**Status**: Ready for implementation  
**Input**: User description: "Promote the remaining support-access governance gap into one bounded enterprise slice. Reuse the repo's current break-glass, system access logs, workspace detail, workspace settings, and audit surfaces. Add request reason, TTL, bounded support scopes, optional approval where risk is high, customer-visible history, exportable support-access audit, and clear separation between ordinary support access and emergency break-glass recovery without introducing a full IAM suite, unrestricted impersonation, or SCIM work."

## Spec Candidate Check *(mandatory - SPEC-GATE-001)*

- **Problem**: The repo already has platform break-glass, the `RepairWorkspaceOwners` recovery utility, system access logs, a system workspace detail page, and a tenant-plane audit log, but it still has no bounded workspace-scoped support-access package that explains who requested access, why it was granted, how long it lasts, whether customer approval was required, and which support scope was active.
- **Today's failure**: A platform operator can enter break-glass and perform workspace-owner recovery with platform-side audit trails, yet workspace owners still do not get one governed support-access lifecycle, one pending approval path for high-risk recovery, one customer-visible history filter, or one exportable support-access log. Support access and emergency recovery remain too easy to blur together.
- **User-visible improvement**: Platform support becomes workspace-scoped, reasoned, time-bounded, and auditable; workspace owners can approve or deny the risky recovery path; admin-plane operators can inspect and export support-access history; and emergency break-glass remains visibly separate from ordinary support access.
- **Smallest enterprise-capable version**: Add one workspace-owned support-access grant record with two bounded scopes (`audit_view` and `workspace_recovery`), request/start/end it from the existing system workspace detail page, require explicit workspace-owner approval only for the recovery scope when owners exist, surface pending approvals on the existing workspace settings page, extend the current admin audit log and system access logs with support-access events, and require both an active recovery grant and active break-glass for the existing owner-repair action.
- **Explicit non-goals**: No unrestricted admin-plane bridge, no customer-user impersonation, no tenant browsing as a customer user, no full IAM suite, no SCIM or group provisioning, no second support console, no support billing workflow, and no broad action-by-action support matrix across all admin pages.
- **Permanent complexity imported**: One new workspace-owned support-access entity, one bounded support-scope catalog, one approval-mode rule, one resolver or manager layer, new audit action identifiers, focused system and admin Filament changes, and unit plus feature coverage.
- **Why now**: Roadmap and audit material already call out break-glass and support-access seams as a blocker before broader delegated-access or SSO or SCIM work. Without this boundary, later delegated support work will either duplicate local guardrails or extend today’s emergency path beyond its intended role.
- **Why not local**: The same support-access truth has to gate system recovery, workspace-owner approval, workspace-visible history, system access logs, and export behavior. Local page-only flags would drift immediately.
- **Approval class**: Core Enterprise
- **Red flags triggered**: New persisted truth, new state family, dual-plane surface changes, and a high-risk recovery workflow. Defense: the slice stays on current repo-real support seams only, keeps support scopes to two concrete cases, and explicitly defers impersonation and unrestricted delegated admin access.
- **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | **Gesamt: 11/12**
- **Decision**: approve

## Spec Scope Fields *(mandatory)*

- **Scope**: workspace
- **Primary Routes**:
  - `/system/directory/workspaces/{workspace}` on `App\Filament\System\Pages\Directory\ViewWorkspace`
  - `/system` on `App\Filament\System\Pages\Dashboard` for existing break-glass context only
  - `/system/repair-workspace-owners` on `App\Filament\System\Pages\RepairWorkspaceOwners`
  - `/system/security/access-logs` on `App\Filament\System\Pages\Security\AccessLogs`
  - `/admin/settings/workspace` on `App\Filament\Pages\Settings\WorkspaceSettings`
  - `/admin/audit-log` on `App\Filament\Pages\Monitoring\AuditLog`
- **Data Ownership**: One new workspace-owned support-access grant history becomes the durable source of truth. Existing `audit_logs` remain the customer-visible history and export substrate. No new tenant-owned truth is introduced.
- **RBAC**: Platform users with `PlatformCapabilities::ACCESS_SYSTEM_PANEL`, `PlatformCapabilities::DIRECTORY_VIEW`, and a new bounded support-access manage capability may request, start, and end support access from the system plane. Workspace owners with `Capabilities::WORKSPACE_SETTINGS_MANAGE` may approve or deny high-risk recovery requests in the admin plane. Workspace members with `Capabilities::WORKSPACE_SETTINGS_VIEW` may inspect current support-access posture, and members with `Capabilities::AUDIT_VIEW` may inspect or export support-access history. Wrong-plane and non-member access remain `404`; in-scope actors missing capability remain `403`.

For canonical-view specs, the spec MUST define:

- **Default filter behavior when tenant-context is active**: N/A - this slice stays on workspace-scoped support access and does not introduce a new canonical tenant collection.
- **Explicit entitlement checks preventing cross-tenant leakage**: Current workspace context and tenant-safe audit-log filters remain authoritative. Support-access history must never expose entries outside the active workspace.

## Cross-Cutting / Shared Pattern Reuse *(mandatory when the feature touches notifications, status messaging, action links, header actions, dashboard signals/cards, alerts, navigation entry points, evidence/report viewers, or any other existing shared operator interaction family; otherwise write `N/A - no shared interaction family touched`)*

- **Cross-cutting feature?**: yes
- **Interaction class(es)**: system detail header actions, status messaging, banners, workspace settings approval affordances, audit-log filtering, export actions, and access-log history
- **Systems touched**: `ViewWorkspace`, `RepairWorkspaceOwners`, `AccessLogs`, `WorkspaceSettings`, `AuditLog`, `BreakGlassSession`, `WorkspaceAuditLogger`, `SystemConsoleAuditLogger`, and the current system or admin audit surfaces
- **Existing pattern(s) to extend**: existing system workspace detail mutation pattern, the current break-glass separation pattern, the current workspace settings singleton surface, and the existing admin or system audit-history surfaces
- **Shared contract / presenter / builder / renderer to reuse**: reuse the current Filament detail and singleton-page patterns, existing audit infrastructure, and current system access-log page instead of creating a second support console; add one bounded `SupportAccessGrantResolver` or manager for shared support-access state
- **Why the existing shared path is sufficient or insufficient**: current surfaces are sufficient for presenting and approving support-access truth, but insufficient because there is no shared support-access lifecycle or workspace-scoped grant truth behind them today
- **Allowed deviation and why**: none. This slice must not create a parallel support UI language, a second history console, or a local one-off approval widget outside the shared surfaces above.
- **Consistency impact**: support scope labels, approval wording, expiry wording, banner copy, and audit action names must stay aligned between system detail, recovery, workspace settings, admin audit history, and system access logs
- **Review focus**: reviewers must verify that support access is presented through the existing detail, settings, and audit families, that break-glass remains visibly separate, and that no second support-control plane appears

## OperationRun UX Impact *(mandatory when the feature creates, queues, deduplicates, resumes, blocks, completes, or deep-links to an `OperationRun`; otherwise write `N/A - no OperationRun start or link semantics touched`)*

N/A - no `OperationRun` start, link, dedupe, or completion semantics are added or changed in this slice. Support-access lifecycle is DB-backed and audit-backed only.

## Provider Boundary / Platform Core Check *(mandatory when the feature changes shared provider/platform seams, identity scope, governed-subject taxonomy, compare strategy selection, provider connection descriptors, or operator vocabulary that may leak provider-specific semantics into platform-core truth; otherwise write `N/A - no shared provider/platform boundary touched`)*

N/A - this slice stays on platform-core support governance and does not change provider or Graph boundaries.

## UI / Surface Guardrail Impact *(mandatory when operator-facing surfaces are changed; otherwise write `N/A`)*

| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / `N/A` Note |
|---|---|---|---|---|---|---|
| System workspace support-access section | yes | Native Filament system detail page | detail summary, header actions, banner messaging | detail page | no | Extends the existing workspace detail page rather than adding a new support console |
| Workspace owner approval section | yes | Native Filament singleton settings page | singleton approval list, support summary | page, section | no | Keeps admin-plane approval on an existing workspace-scoped page |
| Admin audit-log support-access filter and export | yes | Native Filament monitoring page | history filter, export action | page, inspect | no | Reuses the current audit history surface instead of creating a dedicated support history page |
| Recovery boundary on `RepairWorkspaceOwners` | yes | Native Filament recovery page | action gating, warning copy, context banner | page, header action | no | The page stays a separately governed recovery utility |
| System access logs support-access expansion | yes | Native Filament system audit table | history scope, read-only list | page | no | Keeps platform auth, break-glass, and support-access events in one security log family |

## Decision-First Surface Role *(mandatory when operator-facing surfaces are changed)*

| Surface | Decision Role | Human-in-the-loop Moment | Immediately Visible for First Decision | On-Demand Detail / Evidence | Why This Is Primary or Why Not | Workflow Alignment | Attention-load Reduction |
|---|---|---|---|---|---|---|---|
| System workspace support-access section | Primary Decision Surface | Platform operator decides whether a workspace needs bounded support access now | Current workspace support posture, active grant summary, pending request state, scope, reason, and expiry | Audit trail, approval lineage, and recent support events remain secondary | Primary because this is the one place where platform support starts or ends workspace-scoped access | Follows the current system workspace triage workflow | Removes the need to correlate dashboard break-glass, recovery page state, and audit history manually |
| Workspace owner approval section | Primary Decision Surface | Workspace owner decides whether to approve or deny a high-risk recovery request | Pending requester, reason, scope, requested TTL, and waiver state | Broader support history stays secondary | Primary because the owner’s approval is the human gate for risky recovery support | Keeps approval inside current workspace settings rather than email or side-channel approval | Removes off-product approval ambiguity |
| Admin audit-log support-access filter and export | Secondary Context Surface | Workspace operator inspects recent support history or exports it | Filtered support-access events with actor, action, scope, and recorded time | Selected-event detail remains on demand | Not primary because it explains what happened after or around the approval decision | Follows the existing audit-history workflow | Avoids building a second history page |
| Recovery boundary on `RepairWorkspaceOwners` | Secondary Context Surface | Platform operator confirms whether recovery is truly allowed now | Active support grant, active break-glass, and missing prerequisite warnings | Full audit lineage remains secondary | Not primary because the decision should already have been made on the workspace detail and settings surfaces | Keeps the emergency action narrow and execution-focused | Makes failure reasons explicit instead of silent 403-only behavior |

## Audience-Aware Disclosure *(mandatory when operator-facing surfaces are changed)*

| Surface | Audience Modes In Scope | Decision-First Default-Visible Content | Operator Diagnostics | Support / Raw Evidence | One Dominant Next Action | Hidden / Gated By Default | Duplicate-Truth Prevention |
|---|---|---|---|---|---|---|---|
| System workspace support-access section | support-platform | Current support posture, scope, reason, requester, approval state, and expiry | Recent support events and waiver details | Raw audit payloads stay on the history surfaces | `Request support access`, `End support access`, or `Open approval context` | Historical raw audit JSON stays hidden behind the existing history pages | The detail summary states the current support state once; history surfaces provide proof rather than repeating the summary |
| Workspace owner approval section | customer-read-only, operator-MSP | Pending requester, scope, reason, TTL, and the exact decision required | Recent support-access summary and waiver context | Raw audit payloads remain on audit pages only | `Approve recovery access` or `Deny request` | Platform-internal break-glass detail stays hidden; only the customer-relevant support request is shown | The approval card shows the current pending request once and links history instead of re-rendering the full timeline |
| Admin audit-log support-access filter and export | operator-MSP | Filtered support-access events for the current workspace | Selected-event detail and related target links | Raw payload detail stays inspect-only | `Export support access history` | Non-support events stay filtered out by default when using the support filter | The page reuses current audit summary rows rather than adding a second support-specific summary header |
| Recovery boundary on `RepairWorkspaceOwners` | support-platform | Whether both active recovery grant and active break-glass exist for the target workspace | Why access is blocked, who approved, and when the grant expires | Full history remains secondary | `Emergency: Assign Owner` | Recovery waiver metadata remains secondary | The page keeps one explicit blocker message instead of duplicating support and break-glass state in multiple places |

## UI/UX Surface Classification *(mandatory when operator-facing surfaces are changed)*

| Surface | Action Surface Class | Surface Type | Likely Next Operator Action | Primary Inspect/Open Model | Row Click | Secondary Actions Placement | Destructive Actions Placement | Canonical Collection Route | Canonical Detail Route | Scope Signals | Canonical Noun | Critical Truth Visible by Default | Exception Type / Justification |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| System workspace support-access section | System / Detail / Diagnostics | Read-only detail with bounded mutation actions | Start or end workspace-scoped support access | Dedicated workspace detail page | forbidden | Secondary history and admin-workspace links stay on the page | None; ending access is high-impact but not destructive | `/system/directory/workspaces` | `/system/directory/workspaces/{workspace}` | Current workspace identity scopes every support action | Support access | Active or pending support access, scope, reason, approval state, and expiry | Existing system-detail exception remains bounded |
| Workspace owner approval section | Config / Settings / Singleton | Singleton workspace settings page | Approve or deny a pending recovery request | In-page approval section | forbidden | History links remain secondary | Deny action stays inline with the pending request | `/admin/settings/workspace` | `/admin/settings/workspace` | Active workspace context | Support access approval | Pending decision, requester, scope, reason, and requested TTL | Existing singleton settings exception remains valid |
| Admin audit-log support-access filter and export | Monitoring / History / Audit | Audit history page | Inspect or export support-access history | Current selected-event inspect model | optional current inspect affordance | Existing header actions remain secondary to export | none | `/admin/audit-log` | `/admin/audit-log?event={auditLogId}` | Active workspace filter and support-access preset | Audit log | Support-access history rows for the current workspace | Existing audit-history inspect model remains authoritative |
| Recovery boundary on `RepairWorkspaceOwners` | System / Recovery Utility | High-risk utility page | Execute owner repair once both prerequisites are satisfied | Dedicated recovery utility page | forbidden | Recent break-glass and support history remain secondary | `Emergency: Assign Owner` stays in the header | `/system/repair-workspace-owners` | `/system/repair-workspace-owners` | Recovery scope and workspace selection stay explicit | Repair workspace owners | Missing support grant or break-glass prerequisite is visible by default | Existing separately governed recovery exception remains valid |

## Operator Surface Contract *(mandatory when operator-facing surfaces are changed)*

| Surface | Primary Persona | Decision / Operator Action Supported | Surface Type | Primary Operator Question | Default-visible Information | Diagnostics-only Information | Status Dimensions Used | Mutation Scope | Primary Actions | Dangerous Actions |
|---|---|---|---|---|---|---|---|---|---|---|
| System workspace support-access section | Platform support operator | Decide whether bounded support access should start or end for one workspace | System detail page | Does this workspace currently need support access, at what scope, and for how long? | Active or pending support-access state, scope, requester, reason, approval, and expiry | Recent support-access events and waiver detail | support-access lifecycle, approval state, expiry state | TenantPilot only | Request support access, End support access | none |
| Workspace owner approval section | Workspace owner | Decide whether risky recovery support may proceed | Singleton settings page | Should this recovery request be approved for this workspace now? | Pending requester, scope, reason, requested TTL, and any waiver need | Recent support-access summary and relevant history links | approval state, support-access lifecycle | TenantPilot only | Approve recovery access, Deny request | Deny request |
| Admin audit-log support-access filter and export | Workspace operator or manager | Review or export support-access history | Monitoring page | What support access happened for this workspace, by whom, and when? | Filtered support-access history rows | Selected-event detail and related target links | audit outcome, support-access lifecycle | none | Export support access history | none |
| Recovery boundary on `RepairWorkspaceOwners` | Platform support operator in emergency recovery | Decide whether owner repair is legally and operationally allowed now | Recovery utility page | Do I have the required support grant and active break-glass for this workspace? | Current blocker or allow state, approval source, and expiry | Recent break-glass actions and support-access history | support-access lifecycle, break-glass state | TenantPilot only | Emergency: Assign Owner | Emergency: Assign Owner |

## Proportionality Review *(mandatory when structural complexity is introduced)*

- **New source of truth?**: yes
- **New persisted entity/table/artifact?**: yes
- **New abstraction?**: yes
- **New enum/state/reason family?**: yes
- **New cross-domain UI framework/taxonomy?**: no
- **Current operator problem**: The product can currently prove break-glass and owner-repair events after the fact, but it cannot express one bounded support-access lifecycle that starts on a workspace, requests approval for risky recovery, and remains inspectable or exportable by the affected workspace.
- **Existing structure is insufficient because**: `BreakGlassSession` is global and session-based, `RepairWorkspaceOwners` only checks platform capability plus active break-glass, and current history surfaces do not distinguish ordinary support access from emergency recovery in a workspace-scoped lifecycle.
- **Narrowest correct implementation**: One workspace-owned support-access grant history plus two concrete scopes, one shared resolver or manager, and extensions to current workspace detail, settings, recovery, and history surfaces.
- **Ownership cost**: One new entity, one new migration, one bounded resolver or manager, one new support-scope catalog, new audit action IDs, and focused feature plus unit coverage.
- **Alternative intentionally rejected**: Reusing break-glass alone was rejected because it stays system-global, customer-invisible, and too broad for ordinary support access. A full impersonation or delegated-access bridge was rejected because it would widen the slice beyond current repo-real support surfaces.
- **Release truth**: current-release truth and bounded future-release preparation for later delegated access or impersonation follow-ups

### Compatibility posture

This feature assumes a pre-production environment.

Backward compatibility, legacy aliases, migration shims, historical fixtures, and compatibility-specific tests are out of scope unless explicitly required by this spec.

Canonical replacement is preferred over preservation.

## Testing / Lane / Runtime Impact *(mandatory for runtime behavior changes)*

- **Test purpose / classification**: Unit, Feature
- **Validation lane(s)**: fast-feedback, confidence
- **Why this classification and these lanes are sufficient**: One new unit family proves support-access grant validation, support-scope mapping, approval behavior, and expiry logic. Focused feature coverage proves system detail request flow, workspace approval, recovery enforcement, and history export without widening into browser or heavy-governance lanes.
- **New or expanded test families**: one new unit family for support-access grant logic plus focused extensions to existing system, auth, settings, monitoring, and access-log feature families
- **Fixture / helper cost impact**: bounded. The slice needs one new grant factory plus existing platform user, workspace, membership, and audit fixtures. No browser harness, provider mock, or queue harness is required.
- **Heavy-family visibility / justification**: none
- **Special surface test profile**: standard-native-filament, shared-detail-family, monitoring-state-page, exception-coded-surface
- **Standard-native relief or required special coverage**: standard Filament feature coverage is sufficient for workspace detail and settings approval. Recovery requires explicit exception-coded coverage because it combines support-access and break-glass prerequisites on a separately governed utility page.
- **Reviewer handoff**: Reviewers must confirm that support access stays workspace-scoped, that `workspace_recovery` never bypasses break-glass, that `audit_view` never mutates customer state, that support-access history is workspace-filtered and exportable, and that the exact proof commands below stay consistent across artifacts.
- **Budget / baseline / trend impact**: low feature-local increase only
- **Escalation needed**: none
- **Active feature PR close-out entry**: Guardrail
- **Planned validation commands**:
  - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/System/SupportAccessGrantResolverTest.php`
  - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/System/SupportAccessRequestFlowTest.php tests/Feature/System/SupportAccessRecoveryBoundaryTest.php tests/Feature/Auth/BreakGlassModeTest.php tests/Feature/Auth/BreakGlassWorkspaceOwnerRecoveryTest.php tests/Feature/System/Spec114/AccessLogsTest.php`
  - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/Settings/WorkspaceSupportAccessApprovalTest.php tests/Feature/Monitoring/AuditLogSupportAccessHistoryTest.php`
  - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`

## Scope Boundaries *(required for this slice)*

### In Scope

- One workspace-owned support-access grant history with bounded states and expiry
- Exactly two support scopes in v1: `audit_view` and `workspace_recovery`
- Support-access request/start/end from the existing system workspace detail surface
- Workspace-owner approval or denial for `workspace_recovery` on the existing workspace settings page
- Support-access banner or support-state summary on current system detail and recovery surfaces
- Support-access history on the existing admin audit log with workspace-safe filtering and export
- Support-access events added to the existing system access logs
- Recovery enforcement that requires both active break-glass and active recovery-scoped support access for the target workspace

### Non-Goals

- Admin-plane impersonation or unrestricted delegated support browsing
- Customer-user session takeover or acting as a tenant member
- SCIM, Entra group provisioning, or SSO expansion
- A full support workflow engine, assignment queue, or ticketing system
- New queue or `OperationRun` families for support access
- Cross-workspace support dashboards beyond the current system detail and history surfaces

## Assumptions

- Ordinary support access in v1 should stay on current repo-real surfaces only; future delegated access or impersonation can extend the grant model later.
- `audit_view` is the low-risk scope and can auto-activate once requested by an authorized platform operator.
- `workspace_recovery` is the high-risk scope and should require explicit workspace-owner approval when at least one owner exists.
- If a workspace has zero owners, `workspace_recovery` may proceed only through an explicit waiver path while break-glass is active; the waiver must be separately audited.
- Break-glass remains a system-wide emergency control and never becomes the ordinary support-access grant itself.

## Risks

- Approval logic can become ambiguous if the product tries to combine ordinary support access and emergency recovery into one state label. The spec avoids that by keeping support scope and break-glass state distinct.
- Support-access history could duplicate current audit summaries if export and filter behavior is not kept on the existing audit pages.
- Recovery support could drift into a de facto impersonation bridge if later work adds more scopes without a new follow-up spec.
- The ownerless-workspace waiver path is intentionally risky and requires extra audit clarity to avoid becoming a silent bypass.

## Deferred Adjacent Candidates

- Delegated admin-plane support browsing and explicit impersonation follow-through
- Workspace-level support policy editing beyond the bounded v1 approval rules
- Ticket or case integration for support access requests
- SCIM or broader SSO work that depends on a stronger support-access boundary

## User Scenarios & Testing *(mandatory)*

### User Story 1 - Request and activate bounded workspace support access (Priority: P1)

As a platform support operator, I want to request workspace-scoped support access with a reason, scope, and expiry so ordinary support work stops depending on the global break-glass mechanism.

**Why this priority**: Without a bounded workspace-scoped grant, the product still cannot distinguish ordinary support access from emergency recovery.

**Independent Test**: Open the existing system workspace detail page, request `audit_view` support access with a reason and TTL, and confirm the page shows the active support grant plus audit history without touching recovery or impersonation flows.

**Acceptance Scenarios**:

1. **Given** an authorized platform operator opens `ViewWorkspace`, **When** they request `audit_view` with a reason and TTL, **Then** the workspace gets one active support-access grant, the page shows the active support state, and the request is audited.
2. **Given** an active `audit_view` grant exists, **When** the operator ends support access from the same workspace detail page, **Then** the grant ends, the active summary disappears, and the end event is audited.
3. **Given** an unauthorized or wrong-plane actor attempts the same request, **When** the request is evaluated, **Then** existing `404` and `403` semantics remain authoritative and no support-access grant is created.

---

### User Story 2 - Approve risky recovery access and keep break-glass separate (Priority: P1)

As a workspace owner and platform recovery operator, I want the risky recovery path to require both workspace approval and emergency break-glass so customer-impacting recovery is explicit, time-bounded, and still visibly distinct from ordinary support access.

**Why this priority**: The current owner-repair utility is exactly where the gap between ordinary support access and emergency recovery is operationally acute.

**Independent Test**: Request `workspace_recovery` on a workspace with an owner, approve it from workspace settings, activate break-glass from the system dashboard, and confirm `RepairWorkspaceOwners` only succeeds when both prerequisites are active.

**Acceptance Scenarios**:

1. **Given** a workspace has at least one owner, **When** a platform operator requests `workspace_recovery`, **Then** the request stays pending until a workspace owner approves or denies it.
2. **Given** a workspace owner approves the pending recovery request, **When** the platform operator opens `RepairWorkspaceOwners` without active break-glass, **Then** the recovery action remains blocked with a clear prerequisite message.
3. **Given** both active break-glass and an active recovery-scoped support grant exist for the selected workspace, **When** the operator executes `Emergency: Assign Owner`, **Then** the action succeeds and records both recovery and support-access audit context.
4. **Given** a workspace has zero owners, **When** the platform operator requests `workspace_recovery`, **Then** the product may use the explicit waiver path only while break-glass is active and must audit the waiver reason.

---

### User Story 3 - Inspect and export customer-visible support-access history (Priority: P2)

As a workspace operator or owner, I want to inspect and export support-access history from current admin audit surfaces so customer-visible support governance does not depend on system-only logs.

**Why this priority**: Customer-safe support governance is incomplete unless the affected workspace can inspect and export the same history the platform can see.

**Independent Test**: Open the current admin audit log in a workspace with support-access events, filter to support-access entries, export the filtered history, and confirm the output stays workspace-scoped.

**Acceptance Scenarios**:

1. **Given** support-access events exist for the current workspace, **When** an authorized admin-plane actor filters the audit log to support-access events, **Then** the page shows only workspace-scoped support-access history.
2. **Given** the same filtered support-access view, **When** the actor exports history, **Then** the export contains support-access events for the current workspace only.
3. **Given** a non-member or wrong-workspace actor attempts the same history view or export, **When** the request is evaluated, **Then** the product preserves existing `404` or `403` behavior and leaks no support-access state.

### Edge Cases

- An active `audit_view` grant must never satisfy the recovery boundary on `RepairWorkspaceOwners`.
- Break-glass may remain active after a support-access grant expires, but recovery must still block when the grant is no longer active.
- Multiple overlapping requests from the same platform user for the same workspace and scope should dedupe into one active or pending grant rather than stack conflicting timers.
- Ownerless-workspace recovery needs an explicit waiver path with its own audit detail so the system does not pretend an approval happened when no owner existed.
- Support-access history export must remain workspace-scoped even when the current admin audit log includes tenant-specific records.

## Requirements *(mandatory)*

**Constitution alignment (required):** This feature adds security-relevant DB-backed support-access truth, approval workflow, and system/admin UI behavior. It adds no Microsoft Graph calls and no new `OperationRun` family. All state changes are audit-backed and confirmation-protected where high risk.

**Constitution alignment (PROP-001 / ABSTR-001 / PERSIST-001 / STATE-001 / BLOAT-001):** The feature introduces a new persisted grant history because support access now needs an independent lifecycle, expiry, approval lineage, and customer-visible history that existing `BreakGlassSession` and ad hoc audit events cannot provide.

**Constitution alignment (XCUT-001):** All new support-access state must flow through one bounded resolver or manager and the existing detail, settings, and audit surfaces. No page may invent its own support-access state or approval wording.

**Constitution alignment (DECIDE-AUD-001 / OPSURF-001):** The system workspace detail page remains the primary support-access decision surface, workspace settings remains the primary approval surface, and current history pages stay secondary. Default-visible content stays decision-first and keeps raw audit detail progressive.

**Constitution alignment (PROV-001):** No provider or Graph boundary changes are introduced.

**Constitution alignment (TEST-GOV-001):** Proof stays in one new unit family plus focused feature extensions to existing system, auth, settings, monitoring, and access-log families.

**Constitution alignment (RBAC-UX):** Two planes are involved: platform `/system` for support-access request and recovery execution, and workspace `/admin` for approval and history. Wrong-plane and non-member access stay `404`. In-scope actors missing capability stay `403`. High-risk actions require `->requiresConfirmation()`.

**Constitution alignment (BADGE-001):** If support-access state or approval state is badge-rendered, labels and colors must come from one bounded mapping rather than page-local semantics.

**Constitution alignment (UI-FIL-001):** This slice extends existing Filament pages only. It must not add a second support console or a custom support design language.

### Functional Requirements

- **FR-276-001 Workspace-owned support-access truth**: The product MUST persist support-access requests and active or ended grants in one new workspace-owned history table rather than in session-only state or free-form audit metadata.
- **FR-276-002 Bounded support-scope catalog**: V1 MUST support exactly two support scopes: `audit_view` and `workspace_recovery`.
- **FR-276-003 Required request fields**: Every support-access request MUST capture workspace, platform actor, scope, reason, requested TTL, requested-at timestamp, and expiry target.
- **FR-276-004 Dedupe rule**: The system MUST prevent overlapping active or pending grants for the same workspace, platform actor, and scope from creating conflicting support timers.
- **FR-276-005 Ordinary support flow**: `audit_view` MUST be requestable from the existing system workspace detail page and may activate immediately for an authorized platform operator because it does not mutate customer state.
- **FR-276-006 Recovery approval rule**: `workspace_recovery` MUST create a pending request that requires explicit workspace-owner approval when the workspace still has at least one owner.
- **FR-276-007 Ownerless recovery waiver**: If a workspace has zero owners, `workspace_recovery` MAY be activated only through an explicit waiver path while break-glass is active, and the waiver reason MUST be audited distinctly.
- **FR-276-008 Break-glass separation**: Support access MUST remain separate from break-glass. `workspace_recovery` never implicitly activates break-glass, and break-glass alone never satisfies the support-access grant requirement.
- **FR-276-009 Recovery boundary enforcement**: `RepairWorkspaceOwners` MUST require both active break-glass and an active `workspace_recovery` grant for the selected workspace before `Emergency: Assign Owner` may execute.
- **FR-276-010 Support-access summary**: `ViewWorkspace` MUST show current support-access posture, including active grant, pending request, scope, requester, approval state, reason, and expiry.
- **FR-276-011 Approval surface**: `WorkspaceSettings` MUST show pending `workspace_recovery` requests to workspace owners with explicit approve or deny actions.
- **FR-276-012 Customer-visible history**: The current admin audit-log page MUST support a support-access filter preset that shows support-access history for the active workspace only.
- **FR-276-013 Exportable history**: Authorized admin-plane actors MUST be able to export current support-access history for the active workspace from the existing audit-log surface.
- **FR-276-014 System security history**: The current system access-log page MUST include support-access lifecycle events alongside platform auth and break-glass events.
- **FR-276-015 Audit action family**: Request, approval, denial, activation, expiry, end, and waiver events MUST write stable audit action IDs and structured metadata.
- **FR-276-016 Capability and membership enforcement**: Platform-side request or end actions MUST use new bounded platform capabilities; admin-side approval or export actions MUST use the current canonical capability registry and workspace membership checks.
- **FR-276-017 No impersonation bridge**: This slice MUST NOT allow platform users to browse or act as customer users across the admin plane outside the bounded support history and approval surfaces.

## UI Action Matrix *(mandatory when Filament is changed)*

| Surface | Location | Header Actions | Inspect Affordance (List/Table) | Row Actions (max 2 visible) | Bulk Actions (grouped) | Empty-State CTA(s) | View Header Actions | Create/Edit Save+Cancel | Audit log? | Notes / Exemptions |
|---|---|---|---|---|---|---|---|---|---|---|
| System workspace support-access section | `app/Filament/System/Pages/Directory/ViewWorkspace.php` | `Request support access`, `End support access` | dedicated workspace detail route only | none | none | N/A | same page owns the bounded mutation actions | N/A | yes | Reuses the current system detail page and keeps one dominant support action family |
| Workspace owner approval section | `app/Filament/Pages/Settings/WorkspaceSettings.php` | none | N/A - singleton settings page | `Approve`, `Deny` on pending request cards only | none | N/A | none | existing settings save flow remains unrelated | yes | Approval stays on the current singleton settings surface |
| Admin support-access history | `app/Filament/Pages/Monitoring/AuditLog.php` | `Export support access history` | existing selected-event inspect affordance | existing inspect action only | none | current clear-filter CTA remains | existing detail header actions remain | N/A | no new audit event for read-only export | The current audit-history page remains authoritative |
| Recovery boundary | `app/Filament/System/Pages/RepairWorkspaceOwners.php` | existing `Emergency: Assign Owner` only | dedicated recovery page only | none | none | current empty state unchanged | same page owns the recovery action | N/A | yes | Existing separately governed recovery utility remains a named exception |
| System access logs | `app/Filament/System/Pages/Security/AccessLogs.php` | none | inline history only | none | none | current empty state unchanged | none | N/A | no new audit event for read-only history | Expand current page scope instead of adding a second system security log |

### Key Entities *(include if feature involves data)*

- `SupportAccessGrant` (new workspace-owned persisted entity)
- `Workspace` (existing owner and scope anchor)
- `PlatformUser` (existing system actor)
- `AuditLog` (existing history substrate)

## Success Criteria *(mandatory)*

### Measurable Outcomes

- **SC-276-001**: An authorized platform operator can request `audit_view` from the existing workspace detail page with a reason and TTL, see the active support summary on that same workspace context, and end the grant again without using break-glass.
- **SC-276-002**: `RepairWorkspaceOwners` remains blocked in every prerequisite combination except the one where active break-glass and an active `workspace_recovery` grant both exist for the selected workspace.
- **SC-276-003**: A workspace owner can approve or deny a pending `workspace_recovery` request from the existing workspace settings page without needing a second approval surface or out-of-band workflow.
- **SC-276-004**: A workspace operator can filter and export support-access history from the existing admin audit-log surface, and the exported history remains limited to the active workspace.
