## 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
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-onlyand no write path is introduced. - Graph contract path: PASS. All RBAC reads will use
GraphClientInterfaceand new config-backed contract entries inconfig/graph_contracts.php. - Deterministic capabilities: PASS. Restore/risk/support metadata stays config-driven via
config('tenantpilot.foundation_types')andInventoryPolicyTypeMeta. - RBAC-UX plane separation: PASS. This stays in the Tenant/Admin plane and reuses existing tenant-scoped capability checks; no
/systemexposure 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
OperationRunrecords 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
OperationRuntransition 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_jsonbstays 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.mdfor the touched list surfaces.
Result (pre-Phase 0): PASS.
- The main design constraint is compatibility: existing
directoryRoleDefinitionsandrbacRoleAssignmentcontracts 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
OperationRuntypes, 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_jsonbrecord. - Which existing
VersionServicecapture andPolicyVersionResourcesurfaces should carry foundation-backed RBAC history alongside backup set detail. - Which existing verification and provider-reason patterns should handle missing
DeviceManagementRBAC.Read.Allas 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
intuneRoleDefinitionandintuneRoleAssignment. - 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):
- Extend
config/tenantpilot.phpfoundation metadata withintuneRoleDefinitionandintuneRoleAssignment, categoryRBAC, andrestore: preview-only. - Add inventory-grade RBAC Graph contracts in
config/graph_contracts.php, preserving existing health/onboarding contract keys. - Wire the new contract keys into foundation inventory and snapshot capture paths, including any Graph contract registry helpers needed for full RBAC reads.
- Add
IntuneRoleDefinitionNormalizerandIntuneRoleAssignmentNormalizer, then register them inAppServiceProvider. - 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.
- Wire RBAC foundation snapshots into the existing
VersionServicecapture and reuse paths so backup capture and version history stay aligned. - Add graceful permission-warning behavior for missing
DeviceManagementRBAC.Read.Allin verification/provider messaging and capture failure metadata. - 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
OperationRunnotification 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
OperationRunflows 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 |