# Feature Specification: Tenant Required Permissions Page (Enterprise Remediation UX)

**Feature Branch**: `076-permissions-enterprise-ui`  
**Created**: 2026-02-05  
**Status**: Draft  
**Input**: User description: "Spec 076 — Tenant Required Permissions Page (Enterprise Remediation UX); upgrade tenant required permissions list into an operator-friendly remediation page with summary, prioritization, feature grouping, guidance, copy-to-clipboard, filters/search, strict tenant-scoped RBAC semantics, badge mapping centralization, DB-only render; plus an enterprise check clustering for verification step (5–7 checks)."

## Clarifications

### Session 2026-02-05

- Q: What capability is required to view the Required permissions page? → A: Require `tenant.view` (Capabilities::TENANT_VIEW). Non-members remain deny-as-not-found.
- Q: What is the overall status mapping for missing permissions? → A: Blocked if any missing application permissions; Needs attention if only delegated permissions are missing; Ready if nothing is missing.
- Q: Should copy-to-clipboard respect filters/search? → A: Copy respects the current Feature filter only; it ignores Search; and it always enforces Status=Missing and Type fixed by the button (app vs delegated).
- Q: Does Spec 076 include Verify-step clustering UI changes? → A: Yes. Spec 076 implements the Required Permissions page and updates the Verify-step UI to show clustered checks (5–7).
- Q: Which centralized badge mappings should be used? → A: Per-permission status uses `BadgeDomain::TenantPermissionStatus`; Overview overall status uses `BadgeDomain::VerificationReportOverall`.

## User Scenarios & Testing *(mandatory)*

### User Story 1 - Operator sees impact at a glance (Priority: P1)

As an Operator, I can immediately understand whether the tenant is blocked, which enabled features are impacted, and how many required permissions are missing.

**Why this priority**: This reduces time-to-diagnosis and prevents “permission soup” confusion during onboarding and incident response.

**Independent Test**: Can be fully tested by loading the page for a tenant with mixed coverage and verifying that the Overview summarizes blocked features and shows “missing-first” by default.

**Acceptance Scenarios**:

1. **Given** a tenant has at least one enabled feature with missing required permissions, **When** I open “Required permissions”, **Then** I see a “Blocked/Needs attention” status and a summary that names impacted features.
2. **Given** a tenant has missing permissions, **When** I first load the page, **Then** the default view shows only missing items and groups them by feature.

---

### User Story 2 - Global Admin can act quickly (Priority: P1)

As a Global Administrator (or delegated privileged operator), I can copy the missing application permissions and missing delegated permissions separately, and I clearly understand that admin consent is required.

**Why this priority**: This turns diagnosis into a one-step remediation action and reduces mistakes (mixing delegated/app permissions).

**Independent Test**: Can be fully tested by verifying that copy actions produce newline-separated permission names for each type and that the guidance block explains “who/how”.

**Acceptance Scenarios**:

1. **Given** there are missing application permissions, **When** I click “Copy missing application permissions”, **Then** my clipboard receives a newline-separated list of the missing application permission names.
2. **Given** there are missing delegated permissions, **When** I click “Copy missing delegated permissions”, **Then** my clipboard receives a newline-separated list of the missing delegated permission names.
3. **Given** any missing permissions exist, **When** I read the guidance section, **Then** it states that a Global Administrator must grant admin consent.

---

### User Story 3 - Deep dive and triage remains possible (Priority: P2)

As an Operator, I can filter and search all required permissions to answer “what exactly is missing, for which feature, and what type is it?”

**Why this priority**: Enables troubleshooting and audit readiness without leaving the product.

**Independent Test**: Can be fully tested by applying filters (Status/Type/Feature) and search terms and verifying table results.

**Acceptance Scenarios**:

1. **Given** a tenant has both present and missing permissions, **When** I change Status to “All”, **Then** I can see both missing and present permissions.
2. **Given** the list contains many permissions, **When** I search by permission key or description, **Then** only matching permissions are shown.

---

### User Story 4 - Unauthorized users see nothing (Priority: P1)

As a non-member of a tenant, I cannot discover the existence of its required permissions page or its contents.

**Why this priority**: Prevents cross-tenant information leakage in enterprise environments.

**Independent Test**: Can be fully tested by requesting the page as (a) a tenant member and (b) a non-member and verifying deny-as-not-found behavior.

**Acceptance Scenarios**:

1. **Given** I am not entitled to the tenant scope, **When** I request the required permissions page, **Then** I receive a not found outcome.
2. **Given** I am entitled to the tenant scope, **When** I request the page, **Then** I can view the summary and permission matrix.

---

### Edge Cases

- What happens when a tenant has zero required permissions (e.g., no enabled features)? Overview MUST show “Ready” and the details list MUST be empty with a clear “nothing required” message.
- What happens when there are no missing permissions? Default “Missing” filter yields an empty state, and Overview MUST show “Ready”.
- How does the system handle a permission that belongs to multiple features? It MUST appear under each relevant feature grouping and contribute to impact counts without double-counting within a feature.
- What happens when copy actions are triggered but there are zero missing permissions of that type? Copy action MUST either be disabled or copy an empty string with an explicit, user-visible message.
- How does the system handle extremely long permission lists? Filtering and search MUST remain usable and stable.

## Requirements *(mandatory)*

### Functional Requirements

- **FR-076-001 — Two-layer layout (Overview + Details)**: The page MUST present two layers:
  - **Layer A (Overview, above the fold)**: status banner, impact summary, counts, next-step actions.
  - **Layer B (Full matrix)**: full list/matrix with filters + search and grouping options.

- **FR-076-002 — Overview content and defaults**: The Overview MUST include:
  1) A status indicator derived from tenant permission coverage (“Ready” / “Needs attention” / “Blocked”).
  2) An impact summary that lists which enabled features are blocked or at risk.
  3) Counts for missing application permissions, missing delegated permissions, and present permissions.
  4) A primary next step that points to an admin consent guide (prefer the existing tenant-specific Admin Consent URL when available; otherwise fall back to an external guide).
  5) Secondary actions for copying missing permissions (application vs delegated).
  6) A visible “Re-run verification” entry point back to the verification experience.

- **FR-076-002a — Overall status mapping (explicit)**: The overall status badge MUST be computed as:
  - **Blocked**: at least one required **application** permission is missing.
  - **Needs attention**: no missing application permissions, but at least one required **delegated** permission is missing.
  - **Ready**: no missing required permissions.

- **FR-076-003 — Missing-first experience**: The default view MUST show only missing permissions. Users MUST be able to switch to “Present” or “All”.

- **FR-076-004 — Feature-based grouping and impact model**: Each permission is tagged with one or more features. The UI MUST aggregate and present per-feature impact, including:
  - missing count per feature
  - required application count per feature
  - required delegated count per feature
  Feature group cards (or equivalent) MUST be clickable to apply a feature filter.

- **FR-076-005 — Full matrix filters and search**: The full matrix MUST support:
  - Status filter: Missing / Present / All
  - Type filter: Application / Delegated / All
  - Feature filter: multi-select across known features
  - Search: substring match by permission key and description

- **FR-076-006 — Copy-to-clipboard formats**: The UI MUST provide:
  - “Copy missing application permissions”
  - “Copy missing delegated permissions”
  Output MUST be newline-separated permission names. An optional “Advanced” action MAY provide a structured (non-secret) export; it MUST not include secrets, identifiers that increase tenant leakage risk, or any credential material.

- **FR-076-006a — Copy semantics with filters**: Copy outputs MUST:
  - Always include only **Missing** permissions.
  - Always include only the permission **Type** corresponding to the clicked button (Application vs Delegated).
  - Respect the **Feature** filter if one is applied.
  - Ignore any free-text **Search** term.

- **FR-076-007 — Operator guidance block**: The page MUST include a static guidance block that answers:
  - “Who can fix this?” (Global Administrator / Privileged Role Administrator)
  - “How long does it take?” (5–10 minutes, optional)
  - “After granting consent” → a clear “Re-run verification” action

- **FR-076-008 — Data source and isolation**: Viewing the page MUST use already-available, stored tenant permission requirement data (no external network calls during page view) and MUST be tenant-scoped.

- **FR-076-009 — RBAC semantics (deny-as-not-found)**: Authorization MUST enforce tenant isolation and avoid leakage:
  - Viewing the page MUST require the `tenant.view` capability.
  - Non-member / not entitled to the tenant scope MUST receive a not found outcome.
  - Member without `tenant.view` MUST receive a forbidden outcome.
  - No global search or cross-tenant navigation entry points may reveal inaccessible tenants or permission contents.

- **FR-076-010 — Badge semantics centralized (BADGE-001)**: Status-like badges used by this feature (e.g., permission status Missing/Present and overall coverage Ready/Needs attention/Blocked) MUST use a centralized semantic mapping/registry. No ad-hoc badge mapping is allowed inside feature UI logic.

- **FR-076-010a — Badge domains (explicit)**: The UI MUST use these centralized badge domains:
  - Per-permission status badge (Missing/Granted/Error): `BadgeDomain::TenantPermissionStatus`
  - Overview overall status badge (Ready/Needs attention/Blocked/Running): `BadgeDomain::VerificationReportOverall`

- **FR-076-011 — Verification check clustering (enterprise UX)**: The verification experience MUST support presenting a reduced set of “checks” (5–7) that cluster individual permissions into operator-friendly topics, while the Required Permissions page remains the deep-dive reference.
  - Each check MUST declare which permissions it covers.
  - Each check MUST compute a deterministic status based on missing vs present permissions relevant to enabled features.
  - Each blocked check MUST provide a next step that routes to the Required Permissions page.

- **FR-076-011a — Verify-step clustered presentation (in scope)**: The Verify-step UI MUST present clustered checks (target 5–7) instead of listing every permission individually, and MUST be issues-first:
  - Blocked checks are shown prominently by default.
  - Each blocked check includes a clear CTA to open the Required Permissions page.
  - The Verify-step retains a way to view passed/ready checks without overwhelming the default view.

- **FR-076-012 — Recommended default checks and mapping**: The product SHOULD use the following check clusters (names can be user-facing, keys are stable identifiers):
  - **C1 Provider authentication works**: can the provider authenticate.
  - **C2 Admin consent granted**: can required admin consent be verified.
  - **C3 Directory & group read access**: directory + groups prerequisites.
  - **C4 Intune configuration access**: configuration + service config permissions.
  - **C5 Intune apps access**: apps permissions.
  - **C6 Intune RBAC & assignments prerequisites**: RBAC permissions.
  - **C7 Scripts/remediations access** (optional): scripts permissions only when relevant features are enabled.

- **FR-076-013 — Cluster status rules (high level)**: For each cluster check:
  - **Pass** when all required permissions for enabled features in that cluster are present.
  - **Blocked** when any required permission is missing that prevents the related enabled features from functioning.
  - **Warning** when only optional/non-blocking permissions are missing.
  - **Skipped** when the cluster is irrelevant because the related feature set is not enabled.

- **FR-076-014 — Desired vs Observed + refresh semantics (enterprise correctness)**:
  - **Desired** permissions MUST come from configuration (`config/intune_permissions.php`).
  - **Observed** permissions MUST come from stored inventory (`tenant_permissions`).
  - The verification run (Operation Run) MUST attempt to refresh Observed inventory from Graph and persist it.
  - Viewer surfaces (onboarding Verify step, operation run viewer, Required Permissions page) MUST remain DB-only at render time.
  - A permission cluster MAY only claim “Missing required permission(s)” when Observed inventory is known-fresh (refreshed successfully during the run).
  - If the Observed refresh fails (e.g. throttling/network), permission clusters MUST degrade to **Warning** (non-blocking) with retry guidance; they MUST NOT assert “Missing” based on stale/empty inventory.
  - Evidence recorded in the verification report MUST remain sanitized and pointer-only (no raw Graph payloads or secrets).

### Assumptions

- The system already maintains a tenant-scoped dataset of required permissions with attributes: permission name, permission type (application/delegated), status (missing/present), and associated features.
- The system already knows which features are enabled for a tenant.
- The Required Permissions page is reachable from the verification experience ("Open required permissions") and provides a "Re-run verification" path back.

### Dependencies

- Existing tenant required permissions dataset and coverage summary.
- Existing verification experience entry points / deep links (including Spec 075 consumer links).

### Out of Scope

- Changing which permissions are required for a feature.
- Granting admin consent inside the product (this feature only guides and prepares the operator/admin).
- Any external network verification calls during page view.
- Any external network verification calls during Required Permissions page view.

### Security & Evidence

- Verification report evidence MUST be safe-by-default:
  - pointer-only (IDs, permission keys, feature tags, HTTP status codes)
  - sanitized (no tokens/secrets)
  - no raw Graph responses or headers

### Validation Notes (what to verify)

- Overview: status + impacted features are visible without scrolling.
- Overview status: Blocked/Needs attention/Ready matches missing application vs delegated logic.
- Defaults: initial view is missing-only and grouped by feature.
- Copy: application and delegated missing lists copy separately and match the current filtered tenant state.
- Copy + filters: feature-filtered copy produces a feature-scoped missing list; search term does not affect copy.
- Filters/search: Status, Type, Feature multi-select, and search all narrow results predictably.
- RBAC: non-members receive a not found outcome; tenant-scoped users can view.
- Badge semantics: all status badges use a centralized mapping.
- Verification step does not produce false “missing permission” findings when inventory refresh fails; it warns and suggests retry.

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

- **Tenant**: A customer environment, with membership/entitlement boundaries.
- **Feature**: A product capability (e.g., backup, restore, drift, policy sync) that depends on permissions.
- **Required Permission**: A named permission requirement with attributes: name, type (application/delegated), status (missing/present), and features[].
- **Permission Coverage Summary**: Precomputed or derivable summary that supports overall status (“Ready/Needs attention/Blocked”) plus counts.
- **Verification Check Cluster**: A named check that groups permissions and reports a status + next-step guidance.

## Success Criteria *(mandatory)*

### Measurable Outcomes

- SC-076-001..003 are product/usability metrics and are not fully enforceable in automated tests. This feature uses proxy assertions (e.g., missing-only default, copy semantics, RBAC negative tests, and ≤ 7 clustered checks) to guard the intended experience.
- **SC-076-001**: In usability testing, operators can identify which features are blocked and why in under 15 seconds on first page load.
- **SC-076-002**: Global admins can copy the missing permission list (application or delegated) with one explicit action, with a task completion rate of at least 95%.
- **SC-076-003**: The default “Missing” view reduces initial on-screen items compared to “All”, and users can reliably narrow results using Status/Type/Feature filters and search with a first-try success rate of at least 90%.
- **SC-076-004**: Unauthorized users (non-members) cannot infer tenant existence or permission requirements via the page or global search entry points (validated by negative access tests).
- **SC-076-005**: Verification step presents no more than 7 permission checks for a tenant, while still reflecting all underlying required permissions.
