TenantAtlas/specs/128-rbac-baseline-compare/tasks.md
ahmido ef41c9193a feat: add Intune RBAC baseline compare support (#156)
## Summary
- add Intune RBAC Role Definition baseline scope support, capture references, compare classification, findings evidence, and landing/detail UI labels
- keep Intune Role Assignments explicitly excluded from baseline compare scope, summaries, findings, and restore messaging
- add focused Pest coverage for baseline scope selection, capture, compare behavior, recurrence, isolation, findings rendering, inventory anchoring, and RBAC summaries

## Verification
- `vendor/bin/sail bin pint --dirty --format agent`
- `vendor/bin/sail artisan test --compact tests/Unit/Inventory/InventoryPolicyTypeMetaBaselineSupportTest.php tests/Unit/Baselines/BaselinePolicyVersionResolverTest.php tests/Unit/Baselines/BaselineScopeTest.php tests/Unit/IntuneRoleDefinitionNormalizerTest.php tests/Feature/Baselines/BaselineCaptureRbacRoleDefinitionsTest.php tests/Feature/Baselines/BaselineCompareRbacRoleDefinitionsTest.php tests/Feature/Baselines/BaselineCompareDriftEvidenceContractRbacTest.php tests/Feature/Baselines/BaselineCompareCoverageGuardTest.php tests/Feature/Baselines/BaselineCompareCrossTenantMatchTest.php tests/Feature/Baselines/BaselineCompareFindingRecurrenceKeyTest.php tests/Feature/Baselines/BaselineCompareWhyNoFindingsReasonCodeTest.php tests/Feature/Filament/BaselineProfileFoundationScopeTest.php tests/Feature/Filament/BaselineSnapshotRbacRoleDefinitionsTest.php tests/Feature/Filament/BaselineCompareLandingRbacLabelsTest.php tests/Feature/Filament/FindingViewRbacEvidenceTest.php tests/Feature/Findings/FindingRecurrenceTest.php tests/Feature/Findings/DriftStaleAutoResolveTest.php tests/Feature/Inventory/InventorySyncButtonTest.php tests/Feature/Inventory/InventorySyncServiceTest.php tests/Feature/RunAuthorizationTenantIsolationTest.php`
- result: `71 passed (467 assertions)`

## Filament / Platform Notes
- Livewire compliance: unchanged and compatible with Livewire v4.0+
- Provider registration: no panel/provider changes; `bootstrap/providers.php` remains the registration location
- Global search: no new globally searchable resource added; existing global search behavior is unchanged
- Destructive actions: no new destructive actions introduced; existing confirmed actions remain unchanged
- Assets: no new Filament assets introduced; deploy asset handling remains unchanged, including `php artisan filament:assets`
- Testing plan covered: baseline profile scope, snapshot detail, compare job, findings recurrence, findings detail, compare landing labels, inventory sync anchoring, and tenant isolation

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #156
2026-03-09 18:49:20 +00:00

223 lines
15 KiB
Markdown

# Tasks: Intune RBAC Baseline Compare & Findings v1 (128)
**Input**: Design documents from `specs/128-rbac-baseline-compare/` (spec.md, plan.md, research.md, data-model.md, contracts/, quickstart.md)
**Prerequisites**: `specs/128-rbac-baseline-compare/plan.md` (required), `specs/128-rbac-baseline-compare/spec.md` (required for user stories)
**Tests**: REQUIRED (Pest) for all runtime behavior changes in this repo.
**Operations**: Reuse the existing `OperationRun` flows for baseline capture and baseline compare; do not add ad-hoc operation feedback, status transitions, or notification patterns.
**RBAC**: Preserve workspace and tenant authorization boundaries, deny-as-not-found 404 for non-members, 403 for in-scope members missing capability, and canonical capability registry usage only.
**Filament UI**: No new Filament resource/page is added; existing baseline profile, snapshot, compare, and findings surfaces are extended only.
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: Reconfirm the exact baseline, RBAC, and findings seams before changing the compare engine.
- [X] T001 Review baseline scope option and profile form seams in `app/Filament/Resources/BaselineProfileResource.php` and `app/Support/Baselines/BaselineScope.php`
- [X] T002 Review baseline capture and compare identity seams in `app/Jobs/CaptureBaselineSnapshotJob.php`, `app/Jobs/CompareBaselineToTenantJob.php`, and `app/Support/Baselines/BaselineSubjectKey.php`
- [X] T003 [P] Review existing Intune RBAC Role Definition normalization and version evidence behavior in `app/Services/Intune/IntuneRoleDefinitionNormalizer.php`, `app/Services/Intune/PolicyNormalizer.php`, and `tests/Unit/IntuneRoleDefinitionNormalizerTest.php`
- [X] T004 [P] Review baseline compare evidence, recurrence, and safety coverage in `tests/Feature/Baselines/BaselineCompareDriftEvidenceContractTest.php`, `tests/Feature/Baselines/BaselineCompareCoverageGuardTest.php`, and `tests/Feature/Findings/FindingRecurrenceTest.php`
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Shared metadata and helper changes that must exist before baseline capture, compare, or UI work can proceed.
**⚠️ CRITICAL**: No user story work should begin until this phase is complete.
- [X] T005 Add explicit baseline-compare support metadata for RBAC foundation types in `config/tenantpilot.php`
- [X] T006 Extend baseline-support helper accessors for foundation types in `app/Support/Inventory/InventoryPolicyTypeMeta.php`
- [X] T007 Update eligible foundation scope options and scope rendering in `app/Filament/Resources/BaselineProfileResource.php`
- [X] T008 [P] Add baseline-support metadata coverage for foundation helpers in `tests/Unit/Inventory/InventoryPolicyTypeMetaBaselineSupportTest.php`
- [X] T009 [P] Add baseline profile foundation scope selection coverage in `tests/Feature/Filament/BaselineProfileFoundationScopeTest.php`
**Checkpoint**: Baseline-supported foundation metadata is explicit, and only eligible foundation types can enter the baseline profile scope.
---
## Phase 3: User Story 1 - Capture an approved RBAC baseline (Priority: P1) 🎯 MVP
**Goal**: Workspace admins can select Intune Role Definitions in a baseline profile and capture baseline snapshot items that keep Role Definition evidence references while excluding Role Assignments.
**Independent Test**: Update a baseline profile to include `intuneRoleDefinition`, run baseline capture, and verify the snapshot contains Role Definition references with evidence-ready metadata while excluding `intuneRoleAssignment`.
### Tests for User Story 1
- [X] T010 [P] [US1] Add baseline capture coverage for Role Definition inclusion and Role Assignment exclusion in `tests/Feature/Baselines/BaselineCaptureRbacRoleDefinitionsTest.php`
- [X] T011 [P] [US1] Add baseline snapshot detail coverage for captured RBAC Role Definition references in `tests/Feature/Filament/BaselineSnapshotRbacRoleDefinitionsTest.php`
### Implementation for User Story 1
- [X] T012 [US1] Extend `CaptureBaselineSnapshotJob` to capture `intuneRoleDefinition` baseline items with explicit identity metadata and version references in `app/Jobs/CaptureBaselineSnapshotJob.php`
- [X] T013 [US1] Add Role Definition-aware baseline subject identity helpers in `app/Support/Baselines/BaselineSubjectKey.php` and `app/Services/Baselines/BaselineSnapshotIdentity.php`
- [X] T014 [US1] Persist evidence-ready baseline metadata for RBAC Role Definition snapshot items in `app/Jobs/CaptureBaselineSnapshotJob.php` and `app/Models/BaselineSnapshotItem.php`
- [X] T015 [US1] Surface captured RBAC Role Definition references in existing snapshot detail presentation via `app/Filament/Resources/BaselineSnapshotResource.php`
**Checkpoint**: User Story 1 is complete when baseline capture stores Role Definition references suitable for later compare and keeps Role Assignments out of the captured baseline scope.
---
## Phase 4: User Story 2 - Detect RBAC drift deterministically (Priority: P1)
**Goal**: Baseline compare classifies Intune Role Definitions as unchanged, modified, missing, or unexpected using Role Definition ID identity and normalized governance diffs.
**Independent Test**: Compare a tenant with prepared Role Definition changes against a captured baseline and verify classification, severity, assignment exclusion, and safe coverage behavior without relying on findings UI.
### Tests for User Story 2
- [X] T016 [P] [US2] Add compare classification coverage for unchanged, modified, missing, and unexpected Role Definitions in `tests/Feature/Baselines/BaselineCompareRbacRoleDefinitionsTest.php`
- [X] T017 [P] [US2] Extend Role Definition normalization coverage for metadata-only versus permission-impacting diffs in `tests/Unit/IntuneRoleDefinitionNormalizerTest.php`
- [X] T018 [P] [US2] Add recreated same-name and different-ID Role Definition coverage in `tests/Feature/Baselines/BaselineCompareRbacRoleDefinitionsTest.php`
- [X] T019 [P] [US2] Add partial-success and coverage-suppression coverage for RBAC compare in `tests/Feature/Baselines/BaselineCompareCoverageGuardTest.php` and `tests/Feature/Baselines/BaselineCompareWhyNoFindingsReasonCodeTest.php`
### Implementation for User Story 2
- [X] T020 [US2] Extend compare-side baseline and current item loading to match `intuneRoleDefinition` by Role Definition ID in `app/Jobs/CompareBaselineToTenantJob.php`
- [X] T021 [US2] Implement normalized RBAC Role Definition diff classification and severity mapping in `app/Jobs/CompareBaselineToTenantJob.php`
- [X] T022 [US2] Reuse `IntuneRoleDefinitionNormalizer::flattenForDiff()` for governance-normalized RBAC compare in `app/Services/Intune/IntuneRoleDefinitionNormalizer.php` and `app/Jobs/CompareBaselineToTenantJob.php`
- [X] T023 [US2] Extend baseline compare evidence resolution for RBAC Role Definition baseline/current version references in `app/Jobs/CompareBaselineToTenantJob.php` and `app/Services/Baselines/Evidence/ContentEvidenceProvider.php`
- [X] T024 [US2] Add RBAC Role Definition summary counts and reason-code context to compare runs in `app/Jobs/CompareBaselineToTenantJob.php` and `app/Support/Baselines/BaselineCompareReasonCode.php`
**Checkpoint**: User Story 2 is complete when compare deterministically classifies Role Definition drift by ID, suppresses false findings when coverage is unsafe, and records RBAC-specific summary counts.
---
## Phase 5: User Story 3 - Review actionable RBAC findings without assignment noise (Priority: P2)
**Goal**: Existing findings and baseline compare surfaces render readable RBAC Role Definition drift evidence, correct labels, and recurrence-safe findings without implying assignment coverage or restore behavior.
**Independent Test**: Open RBAC findings detail and compare detail surfaces after a Role Definition drift run and verify titles, evidence, severity, recurrence behavior, and assignment exclusion.
### Tests for User Story 3
- [X] T025 [P] [US3] Add RBAC evidence contract coverage for modified, missing, and unexpected Role Definition findings in `tests/Feature/Baselines/BaselineCompareDriftEvidenceContractRbacTest.php`
- [X] T026 [P] [US3] Add RBAC finding idempotency and recurrence coverage in `tests/Feature/Baselines/BaselineCompareFindingRecurrenceKeyTest.php` and `tests/Feature/Findings/FindingRecurrenceTest.php`
- [X] T027 [P] [US3] Add Filament coverage for RBAC labels, readable evidence, and no-restore/no-assignment messaging in `tests/Feature/Filament/BaselineCompareLandingRbacLabelsTest.php` and `tests/Feature/Filament/FindingViewRbacEvidenceTest.php`
- [X] T028 [P] [US3] Add tenant/workspace isolation coverage for RBAC baseline compare in `tests/Feature/Baselines/BaselineCompareCrossTenantMatchTest.php` and `tests/Feature/RunAuthorizationTenantIsolationTest.php`
### Implementation for User Story 3
- [X] T029 [US3] Extend baseline.compare finding evidence payloads for `intuneRoleDefinition` in `app/Jobs/CompareBaselineToTenantJob.php`
- [X] T030 [US3] Add RBAC-specific summary kinds, titles, and readable evidence labels in `app/Filament/Pages/BaselineCompareLanding.php`, `lang/en/baseline-compare.php`, and `lang/en/findings.php`
- [X] T031 [US3] Render RBAC drift evidence and labels in existing findings surfaces via `app/Filament/Resources/FindingResource.php`, `app/Filament/Resources/FindingResource/Pages/ViewFinding.php`, `app/Filament/Widgets/Dashboard/RecentDriftFindings.php`, and `app/Filament/Pages/BaselineCompareLanding.php`
- [X] T032 [US3] Keep RBAC findings aligned with explicit fingerprint composition, unified auto-close, and recurrence behavior in `app/Jobs/CompareBaselineToTenantJob.php` and `app/Services/Baselines/BaselineAutoCloseService.php`
**Checkpoint**: User Story 3 is complete when RBAC drift appears in the existing compare and findings surfaces with readable evidence, correct labels, stable recurrence behavior, and no assignment or restore leakage.
---
## Phase 6: Polish & Cross-Cutting Concerns
**Purpose**: Final regression protection, formatting, and QA across all stories.
- [ ] T033 [P] Add or update focused regression coverage for unchanged baseline compare behavior on non-RBAC types in `tests/Feature/Baselines/BaselineCompareFindingsTest.php` and `tests/Feature/Guards/Spec116OneEngineGuardTest.php`
- [ ] T034 [P] Add or update compare-run stats coverage for RBAC summary buckets in `tests/Feature/Baselines/BaselineCompareStatsTest.php`
- [ ] T035 Run formatting for changed files with `vendor/bin/sail bin pint --dirty --format agent`
- [ ] T036 Run focused Pest verification from `specs/128-rbac-baseline-compare/quickstart.md`
- [ ] T037 Validate the manual QA checklist in `specs/128-rbac-baseline-compare/quickstart.md`
---
## Dependencies & Execution Order
### Phase Dependencies
- **Setup (Phase 1)**: No dependencies; can start immediately.
- **Foundational (Phase 2)**: Depends on Setup; blocks all user stories.
- **User Story 1 (Phase 3)**: Depends on Foundational completion.
- **User Story 2 (Phase 4)**: Depends on Foundational completion and benefits from US1 because captured Role Definition baseline items become the approved compare input.
- **User Story 3 (Phase 5)**: Depends on US2 because findings and UI evidence depend on compare outputs and recurrence-safe finding generation.
- **Polish (Phase 6)**: Depends on all desired user stories being complete.
### User Story Dependencies
- **US1 (P1)**: First deliverable and MVP. No dependency on other user stories.
- **US2 (P1)**: Depends on the same shared metadata gates as US1 and on captured baseline Role Definition references.
- **US3 (P2)**: Depends on compare results and findings from US2.
### Within Each User Story
- Tests should be added before or alongside implementation and must fail before the story is considered complete.
- Metadata and identity model changes precede compare and UI changes.
- Compare behavior should be complete before evidence and label presentation work begins.
- Story completion requires focused tests for that story to pass.
### Parallel Opportunities
- Setup review tasks `T003` and `T004` can run in parallel.
- In Phase 2, helper and test tasks `T008` and `T009` can run in parallel after metadata changes begin.
- In US1, `T010` and `T011` can run in parallel, then `T013` and `T015` can proceed in parallel once `T012` defines the capture shape.
- In US2, test tasks `T016` to `T019` can run in parallel, and implementation tasks `T021` to `T024` can be split once `T020` establishes Role Definition ID matching.
- In US3, test tasks `T025` to `T028` can run in parallel, and UI tasks `T030` and `T031` can proceed in parallel after evidence shape is defined in `T029`.
---
## Parallel Example: User Story 1
```bash
# Launch US1 tests in parallel:
T010 tests/Feature/Baselines/BaselineCaptureRbacRoleDefinitionsTest.php
T011 tests/Feature/Filament/BaselineSnapshotRbacRoleDefinitionsTest.php
# Launch US1 follow-up implementation in parallel after capture shape exists:
T013 app/Support/Baselines/BaselineSubjectKey.php + app/Services/Baselines/BaselineSnapshotIdentity.php
T015 app/Filament/Resources/BaselineSnapshotResource.php
```
## Parallel Example: User Story 2
```bash
# Launch US2 tests in parallel:
T016 tests/Feature/Baselines/BaselineCompareRbacRoleDefinitionsTest.php
T017 tests/Unit/IntuneRoleDefinitionNormalizerTest.php
T019 tests/Feature/Baselines/BaselineCompareCoverageGuardTest.php
# Launch US2 implementation in parallel after ID-based loading is in place:
T021 app/Jobs/CompareBaselineToTenantJob.php
T023 app/Services/Baselines/Evidence/ContentEvidenceProvider.php
T024 app/Support/Baselines/BaselineCompareReasonCode.php
```
## Parallel Example: User Story 3
```bash
# Launch US3 tests in parallel:
T025 tests/Feature/Baselines/BaselineCompareDriftEvidenceContractRbacTest.php
T026 tests/Feature/Baselines/BaselineCompareFindingRecurrenceKeyTest.php
T027 tests/Feature/Filament/BaselineCompareLandingRbacLabelsTest.php
# Launch US3 UI work in parallel after evidence payloads are defined:
T030 app/Filament/Pages/BaselineCompareLanding.php + lang/en/baseline-compare.php + lang/en/findings.php
T031 app/Filament/Widgets/Dashboard/RecentDriftFindings.php
```
---
## Implementation Strategy
### MVP First (User Story 1 Only)
1. Complete Phase 1: Setup.
2. Complete Phase 2: Foundational.
3. Complete Phase 3: User Story 1.
4. Validate baseline profile scope selection and baseline capture for `intuneRoleDefinition` independently.
### Incremental Delivery
1. Ship US1 to establish Role Definition baseline eligibility and capture references.
2. Add US2 to deliver deterministic RBAC compare and finding generation.
3. Add US3 to make findings readable and operationally safe in existing UI surfaces.
### Suggested MVP Scope
- MVP = Phases 1 through 3, then run the focused capture tests from `specs/128-rbac-baseline-compare/quickstart.md`.
---
## Format Validation
- Every task follows the checklist format `- [ ] T### [P?] [US?] Description with file path`.
- Setup, Foundational, and Polish phases intentionally omit story labels.
- User story phases use `[US1]`, `[US2]`, and `[US3]` labels.
- Parallel markers are applied only where tasks can proceed independently on separate files or clearly separable work.