Implements workspace-scoped managed tenant onboarding wizard (Filament v5 / Livewire v4) with strict RBAC (404/403 semantics), resumable sessions, provider connection selection/creation, verification OperationRun, and optional bootstrap. Removes legacy onboarding entrypoints and adds Pest coverage + spec artifacts (073). ## Summary <!-- Kurz: Was ändert sich und warum? --> ## Spec-Driven Development (SDD) - [ ] Es gibt eine Spec unter `specs/<NNN>-<feature>/` - [ ] Enthaltene Dateien: `plan.md`, `tasks.md`, `spec.md` - [ ] Spec beschreibt Verhalten/Acceptance Criteria (nicht nur Implementation) - [ ] Wenn sich Anforderungen während der Umsetzung geändert haben: Spec/Plan/Tasks wurden aktualisiert ## Implementation - [ ] Implementierung entspricht der Spec - [ ] Edge cases / Fehlerfälle berücksichtigt - [ ] Keine unbeabsichtigten Änderungen außerhalb des Scopes ## Tests - [ ] Tests ergänzt/aktualisiert (Pest/PHPUnit) - [ ] Relevante Tests lokal ausgeführt (`./vendor/bin/sail artisan test` oder `php artisan test`) ## Migration / Config / Ops (falls relevant) - [ ] Migration(en) enthalten und getestet - [ ] Rollback bedacht (rückwärts kompatibel, sichere Migration) - [ ] Neue Env Vars dokumentiert (`.env.example` / Doku) - [ ] Queue/cron/storage Auswirkungen geprüft ## UI (Filament/Livewire) (falls relevant) - [ ] UI-Flows geprüft - [ ] Screenshots/Notizen hinzugefügt ## Notes <!-- Links, Screenshots, Follow-ups, offene Punkte --> Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.fritz.box> Reviewed-on: #88
186 lines
15 KiB
Markdown
186 lines
15 KiB
Markdown
# Feature Specification: Unified Managed Tenant Onboarding Wizard (073)
|
|
|
|
**Feature Branch**: `073-unified-managed-tenant-onboarding-wizard`
|
|
**Created**: 2026-02-03
|
|
**Status**: Draft
|
|
**Input**: User description: "Single, unified onboarding wizard for Managed Tenants (create/attach connection, verify, optional bootstrap), removing all legacy entry points."
|
|
|
|
## Clarifications
|
|
|
|
### Session 2026-02-03
|
|
|
|
- Q: Which workspace roles can start the onboarding wizard? → A: Only `owner` and `manager`.
|
|
- Q: If Provider Connections already exist, what should Step 2 do? → A: Auto-use the existing default connection (and allow switching).
|
|
- Q: What is the canonical uniqueness key for a Managed Tenant? → A: Unique globally by `tenant_id` (Entra tenant ID) and bound to exactly one workspace.
|
|
- Q: Which Managed Tenant status values exist in v1? → A: `pending`, `active`, `archived`.
|
|
- Q: Who can resume an existing onboarding session? → A: Any workspace `owner/manager` with the onboarding capability (shared session per tenant).
|
|
|
|
## User Scenarios & Testing *(mandatory)*
|
|
|
|
### User Story 1 - Start Managed Tenant onboarding (Priority: P1)
|
|
|
|
As a workspace member with the required capability, I can start a single guided onboarding flow that creates (or resumes) a Managed Tenant in the current workspace, so that the tenant is always created consistently and safely.
|
|
|
|
**Why this priority**: This is the primary entry point and eliminates inconsistent/unsafe creation paths.
|
|
|
|
**Independent Test**: Can be fully tested by starting the onboarding in an empty workspace, completing step 1, and confirming a single Managed Tenant exists and is bound to that workspace.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** a user has selected a workspace and has permission to onboard tenants, **When** they complete “Identify Managed Tenant”, **Then** exactly one Managed Tenant record exists for that workspace and tenant identifier.
|
|
2. **Given** a user repeats the same step with the same tenant identifier, **When** they submit again, **Then** no duplicate Managed Tenant is created and the existing onboarding session is continued.
|
|
|
|
---
|
|
|
|
### User Story 2 - Configure a connection and verify access (Priority: P2)
|
|
|
|
As a workspace member with the required capability, I can configure (or attach) a Provider Connection for the Managed Tenant and trigger a verification run, so that connectivity and permissions are validated without exposing secrets.
|
|
|
|
**Why this priority**: Without a validated connection, the tenant cannot be safely managed.
|
|
|
|
**Independent Test**: Can be tested by completing the “Connection” step and starting a verification run, then asserting the run is created with the expected scope and that no secrets appear in run outputs.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** a Managed Tenant exists in the current workspace, **When** a user configures a connection, **Then** the system stores the connection as configured without ever showing stored secret material back to the user.
|
|
2. **Given** a user confirms they granted consent, **When** they trigger verification, **Then** a background verification run is started and is visible as “queued / running / succeeded / failed” with a sanitized outcome.
|
|
|
|
---
|
|
|
|
### User Story 3 - Resume and complete onboarding (Priority: P3)
|
|
|
|
As a workspace member, I can resume an incomplete onboarding session and complete optional bootstrap actions, so that interrupted onboarding does not create duplicates and finishes in a “ready” state.
|
|
|
|
**Why this priority**: Real onboarding often pauses for consent/approvals; resumability reduces rework and errors.
|
|
|
|
**Independent Test**: Can be tested by starting onboarding, leaving it incomplete, resuming, and finishing; then verifying the tenant is “ready” and optional actions create separate runs.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** onboarding was started but not completed, **When** the user returns later, **Then** they can resume at the correct step with previously entered (non-secret) state.
|
|
2. **Given** verification succeeded, **When** the user chooses optional bootstrap actions, **Then** each selected action starts its own background run and onboarding can still be completed.
|
|
|
|
---
|
|
|
|
### Edge Cases
|
|
|
|
- Cross-workspace isolation: a tenant identifier that exists in a different workspace must not be attachable or discoverable (deny-as-not-found).
|
|
- Missing capability: members without the required capability see disabled UI affordances, and server-side requests are denied.
|
|
- Roles and capabilities: `operator` and `readonly` members cannot start onboarding by default.
|
|
- Resume permissions: onboarding can be resumed by any authorized workspace `owner/manager` (not only the initiator).
|
|
- Verification failures: outcomes must be actionable (reason code + safe message) and never leak tokens/secrets.
|
|
- Idempotency: repeated submissions or refreshes must not create duplicate tenants, duplicate default connections, or a runaway number of active verification runs.
|
|
- Last-owner protections: demoting/removing the last owner (workspace or managed tenant) is blocked and recorded for audit.
|
|
|
|
## 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.
|
|
|
|
### Scope & Assumptions
|
|
|
|
**In scope (v1)**
|
|
|
|
- A single onboarding wizard to create or resume onboarding of a Managed Tenant within a selected workspace.
|
|
- Configure or attach a Provider Connection, guide consent, start verification runs, and optionally start bootstrap runs.
|
|
- Completion marks the tenant as ready/active and routes the user to the tenant details.
|
|
- Removal of all legacy UI entry points for creating/onboarding tenants (no redirects).
|
|
|
|
**Out of scope (v1)**
|
|
|
|
- User invitation workflows.
|
|
- Group-based auto-provisioning.
|
|
- Full compliance/evidence reporting.
|
|
- Cloud resource provisioning.
|
|
|
|
**Dependencies**
|
|
|
|
- Workspace selection/context and workspace membership.
|
|
- A managed-tenant concept bound to exactly one workspace.
|
|
- Provider Connections and secure credential storage.
|
|
- A run system to track verification and bootstrap actions.
|
|
- Audit logging and a canonical capability registry.
|
|
|
|
**Assumptions**
|
|
|
|
- Default policy: the onboarding initiator becomes workspace manager and managed-tenant owner (or the closest minimum-privilege equivalents).
|
|
- “Not found” behavior is used to avoid leaking the existence of out-of-scope tenants.
|
|
|
|
### Acceptance Coverage
|
|
|
|
The following acceptance coverage is required to treat the feature as complete:
|
|
|
|
- Legacy entry points removed (not found behavior).
|
|
- Workspace isolation enforced (cross-workspace attach/visibility prevented).
|
|
- Idempotency verified (no duplicates created by repeated submissions).
|
|
- Verification run creation and sanitized failure reporting.
|
|
- Last-owner protections enforced and auditable.
|
|
|
|
### Functional Requirements
|
|
|
|
- **FR-001 (Single entry point)**: System MUST provide exactly one UI flow to onboard a Managed Tenant (the onboarding wizard), and all other “add tenant” entry points MUST be removed and behave as “not found”.
|
|
- **FR-002 (Workspace-first enforcement)**: System MUST require an active workspace context for onboarding and tenant-scoped access.
|
|
- **FR-003 (Hard isolation)**: System MUST deny-as-not-found (404 semantics) when a Managed Tenant does not belong to the current workspace, including for attempts to attach an existing tenant identifier from another workspace.
|
|
- **FR-004 (Authorization semantics)**: System MUST enforce authorization server-side for all onboarding mutations and run-start actions. Non-member / not entitled to tenant scope MUST be treated as 404 semantics; a member lacking the required capability MUST be treated as 403 semantics. By default, only workspace `owner` and `manager` can start the onboarding wizard.
|
|
- **FR-005 (Capabilities-first)**: System MUST authorize via canonical capabilities (not role string comparisons in feature code).
|
|
- **FR-006 (Idempotent tenant identification)**: System MUST upsert tenant identification by a stable tenant identifier within the workspace, so repeating step 1 never creates duplicates.
|
|
- **FR-006a (Tenant uniqueness key)**: System MUST enforce a single Managed Tenant globally per `tenant_id` (Entra tenant ID) and bind it to exactly one workspace.
|
|
- **FR-007 (Onboarding session resumability)**: System MUST persist onboarding state (excluding secret material) so the flow can be resumed after interruption without data inconsistency.
|
|
- **FR-007a (Shared resumability)**: An onboarding session MUST be resumable by any authorized workspace `owner/manager` with the onboarding capability (not only the user who started it).
|
|
- **FR-008 (Connection handling)**: System MUST allow creating or attaching a Provider Connection during onboarding and MUST never display stored secret material back to users; UI MUST only show safe configuration indicators (e.g., configured yes/no, last rotation timestamp).
|
|
- **FR-008a (Default connection selection)**: If one or more Provider Connections already exist for the Managed Tenant, Step 2 MUST auto-select the default connection and MAY allow the user to switch to a different existing connection.
|
|
- **FR-009 (Verification as runs)**: System MUST start verification as a background run with clear status and a sanitized result (reason code + short safe message).
|
|
- **FR-010 (DB-only UI rendering)**: System MUST render onboarding UI using only stored data; any external calls required for verification MUST occur only in background work.
|
|
- **FR-011 (Operational clarity)**: System MUST display verification outcomes and missing requirements in a user-actionable way (what is missing, what to do next) without leaking sensitive details.
|
|
- **FR-012 (Optional bootstrap actions)**: System MUST support optional post-verify bootstrap actions that each start their own background run and do not block completion unless explicitly selected.
|
|
- **FR-013 (Completion state)**: System MUST mark the Managed Tenant as ready/active only after successful verification, and MUST redirect users to the Managed Tenant details view upon completion.
|
|
- **FR-013a (Status model)**: System MUST use a v1 Managed Tenant lifecycle with statuses: `pending` (created/onboarding), `active` (ready), `archived` (no longer managed).
|
|
- **FR-014 (Membership bootstrap)**: System MUST ensure the onboarding initiator receives the minimum required memberships in the workspace and the managed tenant scope according to policy (default: workspace manager + tenant owner).
|
|
- **FR-015 (Last-owner protections)**: System MUST block demotion/removal of the last owner at both workspace scope and managed tenant scope, and MUST record the blocked attempt for audit.
|
|
- **FR-016 (Auditability)**: System MUST record audit events for tenant creation, connection creation/rotation, verification start/result, membership changes, and last-owner blocks.
|
|
|
|
### Key Entities *(include if feature involves data)*
|
|
|
|
- **Workspace**: A portfolio/customer context that owns memberships and one or more Managed Tenants.
|
|
- **Managed Tenant**: A managed Entra/Intune tenant, uniquely identified within a workspace by an external tenant identifier, with lifecycle status (e.g., pending/ready/archived).
|
|
- Uniqueness: exactly one globally per `tenant_id` (Entra tenant ID), bound to exactly one workspace.
|
|
- Status values (v1): `pending`, `active`, `archived`.
|
|
- **Provider Connection**: A technical connection configuration that enables access to a Managed Tenant; includes secure credentials/configuration metadata and enabled/default flags.
|
|
- **Onboarding Session**: A persistent record of onboarding progress and safe state to support resumability and idempotency.
|
|
- **Verification Run**: A background run that validates connectivity and required permissions and produces a sanitized outcome.
|
|
- **Membership (Workspace-scoped / Tenant-scoped)**: Defines who can see and operate within a workspace and on a specific managed tenant.
|
|
|
|
## Success Criteria *(mandatory)*
|
|
|
|
### Measurable Outcomes
|
|
|
|
- **SC-001 (Time-to-onboard)**: A workspace admin can complete the wizard up to starting verification in under 3 minutes (excluding external consent/approval waiting time).
|
|
- **SC-002 (Idempotency)**: Re-running any wizard step does not create duplicates (0 duplicate tenants per tenant identifier per workspace; 0 duplicate default connections per tenant).
|
|
- **SC-003 (Authorization correctness)**: For all onboarding endpoints/actions, non-members see no discoverability and get 404 semantics; members without capability get 403 semantics; authorized users can complete the flow.
|
|
- **SC-004 (Secret safety)**: No secrets/tokens are present in run outputs, notifications, audit entries, or error messages (validated by automated tests that assert redaction/sanitization behavior).
|
|
- **SC-005 (Operational clarity)**: When verification fails, users can identify the failure reason category (via reason code + safe message) and see the next step without contacting support.
|
|
|
|
### Badge Semantics (BADGE-001)
|
|
|
|
- Managed Tenant status badges MUST map from the canonical status set (`pending`, `active`, `archived`) using a centralized mapping (no ad-hoc per-page mapping).
|