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

11 KiB

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)

specs/127-rbac-inventory-backup/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
└── tasks.md

Source Code (repository root)

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:

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