TenantAtlas/specs/127-rbac-inventory-backup/plan.md
ahmido c6e7591d19 feat: add Intune RBAC inventory and backup support (#155)
## Summary
- add Intune RBAC role definitions and role assignments as foundation-backed inventory, backup, and versioned snapshot types
- add RBAC-specific normalization, coverage, permission-warning handling, and preview-only restore safety behavior across existing Filament and service surfaces
- add spec 127 artifacts, contracts, audits, and focused regression coverage for inventory, backup, versioning, verification, and authorization behavior

## Testing
- `vendor/bin/sail bin pint --dirty --format agent`
- `vendor/bin/sail artisan test --compact tests/Feature/Inventory/InventorySyncServiceTest.php tests/Feature/Filament/InventoryCoverageTableTest.php tests/Feature/FoundationBackupTest.php tests/Feature/Filament/RestoreExecutionTest.php tests/Feature/RestoreUnknownPolicyTypeSafetyTest.php tests/Unit/GraphContractRegistryTest.php tests/Unit/FoundationSnapshotServiceTest.php tests/Feature/Verification/IntuneRbacPermissionCoverageTest.php tests/Unit/IntuneRoleDefinitionNormalizerTest.php tests/Unit/IntuneRoleAssignmentNormalizerTest.php`

## Notes
- tasks in `specs/127-rbac-inventory-backup/tasks.md` are complete except `T041`, which is the documented manual QA validation step

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #155
2026-03-09 10:40:51 +00:00

173 lines
11 KiB
Markdown

# Implementation Plan: Intune RBAC Inventory & Backup v1
**Branch**: `127-rbac-inventory-backup` | **Date**: 2026-03-09 | **Spec**: `/specs/127-rbac-inventory-backup/spec.md`
**Input**: Feature specification from `/specs/127-rbac-inventory-backup/spec.md`
**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/scripts/` for helper scripts.
## Summary
Add Intune Role Definitions and Intune Role Assignments as first-class foundation types in the existing tenant inventory and backup/version architecture.
The implementation reuses the current config-driven foundation flow in `config/tenantpilot.php`, inventory sync persistence through `App\Services\Inventory\InventorySyncService`, foundation backup capture through `App\Services\Intune\FoundationSnapshotService` + `App\Services\Intune\BackupService`, version history capture through `App\Services\Intune\VersionService`, and normalized rendering through `App\Services\Intune\PolicyNormalizer` with new type-specific normalizers. Existing backup set detail and policy version history/detail surfaces will render the new RBAC history without adding a dedicated RBAC resource. To avoid regressions with existing RBAC health and onboarding paths, the plan uses new inventory-grade Graph contract keys for Intune RBAC objects while preserving the existing `directoryRoleDefinitions` and `rbacRoleAssignment` contract semantics already used elsewhere.
## Technical Context
**Language/Version**: PHP 8.4 (Laravel 12)
**Primary Dependencies**: Filament v5, Livewire v4, Laravel Sail, Microsoft Graph provider stack
**Storage**: PostgreSQL for tenant-owned inventory, backup items, versions, verification outcomes, and operation runs
**Testing**: Pest v4 on PHPUnit 12
**Target Platform**: Web app (tenant/admin Filament panel and tenant-scoped operational flows)
**Project Type**: Laravel monolith with config-driven inventory and backup services
**Performance Goals**: preserve current inventory-sync and backup runtime characteristics; no additional render-time Graph calls; RBAC normalization remains deterministic and diff-safe for audit use
**Constraints**: Graph access only via `GraphClientInterface` + contract registry; no write or restore-execution path; strict workspace and tenant isolation; preview-only restore semantics; graceful warning path for missing `DeviceManagementRBAC.Read.All`; metadata-only inventory storage with full payloads only in immutable snapshots/backups
**Scale/Scope**: two new foundation types spanning config, Graph contracts, inventory sync, backup items, version history entries, normalized snapshot display, coverage, verification messaging, and focused regression tests
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
- Inventory-first: PASS. RBAC inventory remains the “last observed” layer via `InventoryItem`; immutable payload history remains explicit in backup/version capture.
- Read/write separation: PASS. This feature is read-only; both RBAC types remain `preview-only` and no write path is introduced.
- Graph contract path: PASS. All RBAC reads will use `GraphClientInterface` and new config-backed contract entries in `config/graph_contracts.php`.
- Deterministic capabilities: PASS. Restore/risk/support metadata stays config-driven via `config('tenantpilot.foundation_types')` and `InventoryPolicyTypeMeta`.
- RBAC-UX plane separation: PASS. This stays in the Tenant/Admin plane and reuses existing tenant-scoped capability checks; no `/system` exposure is added.
- Workspace isolation: PASS. Inventory, backup items, versions, and verification results remain workspace-bound through existing tenant-owned models.
- RBAC-UX destructive confirmation: PASS by exemption. No new destructive action is introduced.
- RBAC-UX global search safety: PASS by non-expansion. No dedicated searchable RBAC resource is added.
- Tenant isolation: PASS. Existing tenant-scoped inventory, backup, version, and verification storage/queries are reused.
- Run observability: PASS. Existing inventory sync and backup/version flows already create `OperationRun` records and remain enqueue-only at start surfaces.
- Ops-UX 3-surface feedback: PASS. The feature reuses existing run types and must not add ad-hoc notifications.
- Ops-UX lifecycle: PASS. No direct `OperationRun` transition logic is added.
- Ops-UX summary counts: PASS. The feature adds coverage and counts through existing inventory and backup flows without changing the summary contract.
- Ops-UX guards: PASS. Existing regression guards remain in force; focused tests will confirm the reused flows still comply after RBAC types are added.
- Ops-UX system runs: PASS. Scheduled and initiator-null behavior is unchanged.
- Automation: PASS. Existing queue, dedupe, and retry behavior for inventory/backup flows is reused.
- Data minimization: PASS. `InventoryItem.meta_jsonb` stays sanitized and payload-heavy RBAC data is stored only in backup/version snapshots.
- Badge semantics (BADGE-001): PASS. Any new support/risk/restore badges must reuse existing badge domains or extend them centrally with tests.
- Filament UI Action Surface Contract / UX-001: PASS by extension-only scope. Existing coverage, backup set detail, and policy version history/detail surfaces are extended with new rows and labels only; no new Filament resource/page is introduced, and the spec references `docs/product/standards/list-surface-review-checklist.md` for the touched list surfaces.
**Result (pre-Phase 0)**: PASS.
- The main design constraint is compatibility: existing `directoryRoleDefinitions` and `rbacRoleAssignment` contracts already serve RBAC health/onboarding flows, so inventory-grade RBAC capture must use separate contract keys instead of silently repurposing those existing keys.
- The feature reuses existing tenant inventory and backup operations; no additional `OperationRun` types, UI workflows, or write gates are needed.
## Project Structure
### Documentation (this feature)
```text
specs/127-rbac-inventory-backup/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
└── tasks.md
```
### Source Code (repository root)
```text
app/
├── Filament/
│ ├── Pages/
│ ├── Resources/
│ └── Widgets/
├── Models/
├── Providers/
├── Services/
│ ├── Graph/
│ ├── Intune/
│ ├── Inventory/
│ └── Providers/
├── Support/
│ ├── Badges/
│ ├── Inventory/
│ ├── Providers/
│ └── Verification/
└── Jobs/
config/
tests/
specs/
```
Expected additions or edits during implementation:
```text
config/tenantpilot.php
config/graph_contracts.php
config/intune_permissions.php
app/Services/Intune/IntuneRoleDefinitionNormalizer.php
app/Services/Intune/IntuneRoleAssignmentNormalizer.php
app/Services/Intune/FoundationSnapshotService.php
app/Services/Intune/VersionService.php
app/Services/Inventory/InventorySyncService.php
app/Support/Inventory/InventoryPolicyTypeMeta.php
app/Support/Verification/TenantPermissionCheckClusters.php
app/Providers/AppServiceProvider.php
app/Filament/Resources/PolicyVersionResource.php
tests/Feature/Inventory/*
tests/Feature/Filament/*
tests/Feature/FoundationBackupTest.php
tests/Feature/BackupServiceVersionReuseTest.php
tests/Feature/Notifications/OperationRunNotificationTest.php
tests/Feature/OpsUx/OperationRunSummaryCountsIncrementTest.php
tests/Unit/*GraphContract*Test.php
tests/Unit/FoundationSnapshotServiceTest.php
tests/Unit/Badges/*
```
**Structure Decision**: Laravel monolith. The feature extends existing config, service, and Filament presentation layers without introducing new top-level directories or a dedicated RBAC resource.
## Phase 0 — Outline & Research
Deliverable: `research.md` with implementation decisions resolved.
Key questions answered in research:
- How to extend foundation registration and coverage classification while keeping deterministic metadata resolution.
- How to add full-fidelity RBAC Graph contracts without breaking current RBAC onboarding and health-check helpers.
- Which storage path should carry immutable RBAC payloads in v1 and how that differs from the sanitized `InventoryItem.meta_jsonb` record.
- Which existing `VersionService` capture and `PolicyVersionResource` surfaces should carry foundation-backed RBAC history alongside backup set detail.
- Which existing verification and provider-reason patterns should handle missing `DeviceManagementRBAC.Read.All` as a soft warning rather than an opaque failure.
- Which existing tests and patterns for foundations, inventory coverage, preview-only restore, and Graph contract sanitization should be reused.
## Phase 1 — Design & Contracts
Deliverables: `data-model.md`, `contracts/*`, `quickstart.md`.
- Data model defines the tenant-owned inventory, backup, version, and verification artifacts affected by `intuneRoleDefinition` and `intuneRoleAssignment`.
- Contracts define the conceptual tenant inventory, coverage, verification, and backup/view behaviors extended by the new RBAC foundation types.
- Quickstart defines the smallest local verification loop using Sail, Pint, and focused Pest tests.
## Phase 2 — Planning
Implementation sequence (high-level):
1. Extend `config/tenantpilot.php` foundation metadata with `intuneRoleDefinition` and `intuneRoleAssignment`, category `RBAC`, and `restore: preview-only`.
2. Add inventory-grade RBAC Graph contracts in `config/graph_contracts.php`, preserving existing health/onboarding contract keys.
3. Wire the new contract keys into foundation inventory and snapshot capture paths, including any Graph contract registry helpers needed for full RBAC reads.
4. Add `IntuneRoleDefinitionNormalizer` and `IntuneRoleAssignmentNormalizer`, then register them in `AppServiceProvider`.
5. Extend coverage and presentation metadata so the RBAC category and both foundation types appear consistently in inventory coverage, backup set detail, and policy version history/detail surfaces.
6. Wire RBAC foundation snapshots into the existing `VersionService` capture and reuse paths so backup capture and version history stay aligned.
7. Add graceful permission-warning behavior for missing `DeviceManagementRBAC.Read.All` in verification/provider messaging and capture failure metadata.
8. Add focused Pest coverage for config registration, Graph contract sanitization, inventory sync, foundation backup capture, version capture/detail, normalized output, coverage visibility, preview-only restore behavior, permission-warning handling, and reused `OperationRun` notification and summary-count invariants.
**Constitution re-check (post-design)**: PASS.
- Inventory remains the observed-state layer; payload-heavy RBAC data remains in immutable backup/version artifacts.
- No write or restore-execution path is added.
- All Graph access remains contract-driven.
- Tenant/workspace isolation and 404/403 rules remain unchanged.
- Existing `OperationRun` flows are reused without adding non-canonical feedback surfaces.
## Complexity Tracking
> **Fill ONLY if Constitution Check has violations that must be justified**
| Violation | Why Needed | Simpler Alternative Rejected Because |
|-----------|------------|-------------------------------------|
| None | N/A | N/A |