TenantAtlas/specs/084-verification-surfaces-unification/spec.md

14 KiB
Raw Blame History

Feature Specification: Verification Surfaces Unification

Feature Branch: 084-verification-surfaces-unification
Created: 2026-02-09
Status: Draft
Input: User description: "Unify tenant + onboarding verification so all verification uses the same run-based mechanism with DB-only viewing and always-available reports (including blocked)."

Clarifications

Session 2026-02-09

  • Q: For tenant members who are in-scope but lack the capability to start verification, how should the “Verify configuration” action behave in the UI? → A: Visible but disabled, with helper text explaining the missing capability (server still enforces 403 if invoked).
  • Q: When rendering the embedded verification viewer on the tenant detail page, which run should be selected as “the last relevant run”? → A: Latest run attempt for that tenant+type (even if queued/running); if active and no report yet, show a DB-only “in progress” state.
  • Q: On the tenant detail page, when no verification run exists yet, what should the embedded verification section do? → A: Show a DB-only empty state with a “Start verification” CTA.
  • Q: For the canonical tenantless run viewer (/admin/operations/{run}), what should be required to view a run that is associated with a tenant? → A: Require both workspace membership AND tenant entitlement; missing either is deny-as-not-found (404).

User Scenarios & Testing (mandatory)

User Story 1 - Verify tenant configuration consistently (Priority: P1)

As a workspace member with the appropriate permission, I can start a tenant verification from the tenant detail view and immediately see the latest stored verification results, without the page performing external provider calls during rendering.

Why this priority: This is the primary operational entry-point and must be fast, safe, and predictable.

Independent Test: Can be fully tested by starting verification from the tenant detail view, asserting a run record exists, and asserting the embedded viewer renders using stored data.

Acceptance Scenarios:

  1. Given a tenant with an eligible provider connection, When I click “Verify configuration”, Then a verification run is started or deduped, and the tenant page renders the report viewer using stored data only.
  2. Given a tenant where verification cannot proceed (e.g., missing consent/credentials), When I click “Verify configuration”, Then a completed “blocked” run exists and the embedded viewer shows a stub/preflight report (not an “unavailable” state).

User Story 2 - Onboarding verify access behaves identically (Priority: P2)

As a workspace member with onboarding verification capability, I can start onboarding verification and receive the same run, dedupe/busy, blocked-report, and canonical link behavior as the tenant verification surfaces.

Why this priority: Removes confusion and reduces operational variance between onboarding and day-2 operations.

Independent Test: Can be tested by starting verification in onboarding and asserting identical run outcomes and viewer behavior to the tenant surface.

Acceptance Scenarios:

  1. Given onboarding verification is started while another verification run is already active for the same target, When I start verification again, Then I receive a busy/deduped result that points to the existing active run.

User Story 3 - Use canonical run links everywhere (Priority: P3)

As a workspace member, I can open the canonical run viewer link from any verification surface and it consistently resolves to the same “tenantless” run route.

Why this priority: Improves supportability and prevents broken/ambiguous deep links.

Independent Test: Can be tested by starting verification, then asserting all “View run” links point to the canonical run route and the page is accessible only to authorized members.

Acceptance Scenarios:

  1. Given a verification run exists, When I click “View run”, Then I am taken to the canonical run viewer route for that run.

Edge Cases

  • Verification is started while an existing run is queued/running for the same target (dedupe/busy behavior must be consistent across surfaces).
  • Verification cannot proceed due to missing consent/credentials (a completed blocked run must still have a schema-valid report).
  • Viewer is opened by a non-member (deny-as-not-found behavior).
  • Stored report data is present but incomplete/invalid (viewer must fail safe with a clear non-leaky message and no external calls).

Non-Functional Requirements

  • NFR-001 (DB-only render): Tenant detail, onboarding verification display, and canonical run viewer rendering MUST be DB-only, with no external provider or Graph calls during mount/render/poll/refresh interactions.
  • NFR-002 (start path latency): Verification start interactions (started, deduped, scope_busy, blocked) SHOULD complete request handling in under 1 second under normal local/staging conditions because they only authorize, create/dedupe run state, enqueue, and notify.
  • NFR-003 (refresh/polling discipline): Verification UI refresh behavior MUST read persisted OperationRun state only and MUST NOT trigger inventory refresh or Graph permission reconciliation during display refresh.

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 (OperationRun type/identity/visibility), and tests. If security-relevant DB-only actions intentionally skip OperationRun, the spec MUST describe AuditLog 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 confirmation (->requiresConfirmation()),
  • 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 OperationRun. 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.

Constitution alignment (Filament Action Surfaces): If this feature adds or modifies any Filament Resource / RelationManager / Page, the spec MUST include a “UI Action Matrix” (see below) and explicitly state whether the Action Surface Contract is satisfied. If the contract is not satisfied, the spec MUST include an explicit exemption with rationale.

Functional Requirements

  • FR-001: System MUST provide a single, unified verification start mechanism used by both the tenant detail “Verify configuration” and onboarding “Verify access” surfaces.
  • FR-002: Starting verification MUST create (or dedupe to) a single “verification run” record for the target, and surface a stable link to view that run.
  • FR-003: When a verification run cannot proceed due to missing prerequisites, the system MUST finalize the run as completed “blocked” and persist a schema-valid stub/preflight verification report.
  • DB-only render invariant: Verification viewers are read-only projections of persisted run/report data; they MUST NOT perform provider/Graph calls and MUST NOT persist permission inventory updates.
  • FR-004: For any verification run that is completed (including blocked), the embedded/onboarding viewers MUST render the verification report using stored data only.
  • FR-004a: The tenant detail embedded viewer MUST select the latest verification run attempt for the tenant and verification type; if that run is active (queued/running) and no report is yet available, the UI MUST render a DB-only “in progress” state.
  • FR-004b: If no verification run exists yet for the tenant and verification type, the tenant detail embedded section MUST show a DB-only empty state with a “Start verification” CTA.
  • FR-005: UI page rendering (including mount/load/summary components) MUST NOT trigger external provider calls directly or indirectly.
  • FR-006: Dedupe rules MUST ensure at most one active run (queued/running) exists per target and verification type; repeated starts during an active run MUST return a busy/deduped outcome.
  • FR-007: The system MUST persist any permissions inventory updates only as part of the verification jobs execution, and MUST NOT persist these updates during page rendering.
  • FR-008: All “View run” links exposed by verification surfaces MUST use the canonical tenantless run viewer route.
  • FR-009: Authorization MUST be enforced server-side:
    • missing workspace membership OR missing tenant entitlement MUST be deny-as-not-found (404) for tenant-scoped routes/actions and tenantless canonical views of tenant-associated records,
    • members lacking the required capability to start verification MUST see the action visible-but-disabled with helper text, and MUST receive a forbidden response (403) if invoked.
  • FR-010: The system MUST emit run observability sufficient for operations (run type, outcome, timestamps, target scope) and MUST be test-covered.

Assumptions & Dependencies

  • This change unifies surfaces and report availability; it does not expand the set of verification checks beyond what is already produced today.
  • For tenant verification surfaces (ViewTenant header action, tenant embedded CTA, and tenant list verify action), “eligible provider connection” means the resolved default provider connection for provider microsoft.
  • Onboarding verification continues to use the session-selected provider connection, and still runs through the same unified operation type and run orchestration.
  • Verification reports are stored with the verification run record and are treated as the sole source for UI rendering.
  • External provider calls are permitted only as part of explicit user-triggered verification runs and their execution (never during page rendering).
  • Existing authorization capabilities and membership rules remain the source of truth; this feature standardizes how they apply across surfaces.

UI Action Matrix (mandatory when Filament is changed)

If this feature adds/modifies any Filament Resource / RelationManager / Page, fill out the matrix below.

For each surface, list the exact action labels, whether they are destructive (confirmation? typed confirmation?), RBAC gating (capability + enforcement helper), and whether the mutation writes an audit log.

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
Tenant detail view Tenant admin area Verify configuration Embedded viewer + View run link n/a n/a Start verification (empty state) n/a n/a Yes DB-only render; starts/dupes run; if missing capability: visible but disabled with helper
Tenant list (Tenants table) Tenant admin area n/a Clickable row + View action Verify configuration (grouped action) grouped n/a n/a n/a Yes Uses same unified start path and canonical run links as tenant detail
Onboarding verification step Onboarding wizard Start verification Embedded viewer + View run link n/a n/a n/a n/a n/a Yes Same semantics as tenant surface
Tenantless run viewer Operations area n/a n/a n/a n/a n/a n/a n/a Yes Requires workspace membership + tenant entitlement; otherwise 404

Key Entities (include if feature involves data)

  • Verification Run: An immutable operational record representing one attempt to verify access/configuration for a target scope. It captures status/outcome and a canonical link for viewing.
  • Verification Report: A schema-valid, stored report attached to a verification run. It is always present for completed runs, including blocked runs (stub/preflight).

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: 100% of completed blocked verification runs display a usable stub report (no "report unavailable" state for completed blocked runs).
  • SC-002: Tenant detail pages render without any external provider calls; verification-related external calls occur only after an explicit start action.
  • SC-003: When a verification run is already active for the same target and type, repeated starts return a busy/deduped response in under 1 second.
  • SC-004: All verification surfaces provide a canonical "View run" link, and support can use that single URL to review outcomes.