# Data Model — Intune RBAC Baseline Compare & Findings v1 ## Entities ### Foundation Type Baseline Metadata Config-defined metadata controlling whether a foundation type can participate in baseline compare. - Source: `config/tenantpilot.php` foundation rows, exposed through `InventoryPolicyTypeMeta` - Required additions: - explicit baseline-compare support flag - optional compare identity strategy marker - optional summary kind or compare label metadata if needed for consistent rendering - Required behavior: - `intuneRoleDefinition` is baseline-supported - `intuneRoleAssignment` is baseline-unsupported ### Baseline Scope Entry The workspace-owned selection stored in `BaselineProfile.scope_jsonb`. - Existing structure: - `policy_types[]` - `foundation_types[]` - New business rule: - `foundation_types[]` may contain `intuneRoleDefinition` - `foundation_types[]` must not contain `intuneRoleAssignment` through normal selection paths - Validation: - selected foundation types must exist in canonical metadata - only baseline-supported foundation types are accepted ### InventoryItem for Intune Role Definition Tenant-owned latest-observed RBAC state used as the current compare anchor. - Existing model/table: `InventoryItem` - Ownership: - `workspace_id` NOT NULL - `tenant_id` NOT NULL - Identity: - `tenant_id + policy_type + external_id` - for this feature, `external_id` is the primary compare identity - Relevant fields: - `policy_type = intuneRoleDefinition` - `external_id` - `display_name` - `category = RBAC` - `platform = all` - `meta_jsonb.is_built_in` - `meta_jsonb.role_permission_count` - `last_seen_at` - `last_seen_operation_run_id` ### PolicyVersion for Intune Role Definition Immutable RBAC snapshot evidence reused for baseline references and diff rendering. - Existing model/table: `PolicyVersion` - Relevant fields: - `tenant_id` - `policy_id` - `policy_type = intuneRoleDefinition` - `snapshot` with Role Definition payload - `captured_at` - `version_number` - Invariant: - enough data exists to normalize display name, description, built-in/custom state, and permissions without live Graph calls ### Baseline Snapshot Item for Intune Role Definition Workspace-owned approved baseline reference used during compare. - Existing model/table: `BaselineSnapshotItem` - Relevant fields: - `baseline_snapshot_id` - `subject_type = policy` or a role-definition-specific variant if introduced narrowly - `subject_external_id` as workspace-safe reference - `subject_key` upgraded to support stable Role Definition identity semantics - `policy_type = intuneRoleDefinition` - `baseline_hash` - `meta_jsonb.display_name` - `meta_jsonb.evidence.*` - `meta_jsonb.identity.external_id` or equivalent explicit identity marker - `meta_jsonb.version_reference` or equivalent baseline PolicyVersion linkage - Validation: - baseline item must keep enough metadata to reconstruct evidence later - baseline snapshot item must not store tenant identifiers directly ### RBAC Role Definition Compare Result Tenant-scoped transient compare outcome created during baseline compare. - Computed attributes: - `policy_type = intuneRoleDefinition` - `role_definition_id` - `classification = unchanged | modified | missing | unexpected` - `severity = low | medium | high` - `built_in_state` - `diff_kind = metadata_only | permission_change | missing | unexpected` - `baseline_hash` - `current_hash` - `baseline_policy_version_id` nullable - `current_policy_version_id` nullable ### RBAC Drift Finding Persistent tenant-owned finding generated through the existing baseline.compare pipeline. - Existing model/table: `Finding` - Relevant fields: - `tenant_id` - `finding_type = drift` - `source = baseline.compare` - `scope_key = baseline_profile:{id}` - `fingerprint` - `recurrence_key` - `subject_type` - `subject_external_id` - `severity` - `status` - `times_seen` - `evidence_jsonb` - `current_operation_run_id` - Invariant: - unchanged identical drift does not create duplicate findings - resolved recurrence reopens through the existing lifecycle rules ### Baseline Compare RBAC Summary Run-level summary stored in compare run context. - Existing container: `OperationRun.context.baseline_compare` - New summary node: - `rbac_role_definitions.total_compared` - `rbac_role_definitions.unchanged` - `rbac_role_definitions.modified` - `rbac_role_definitions.missing` - `rbac_role_definitions.unexpected` - Constraint: - keep rich counts in `context`; do not add non-canonical summary keys to `summary_counts` ## Relationships - A `BaselineProfile` belongs to one workspace and has one active scope definition. - A `BaselineProfile` has many `BaselineSnapshot` records. - A `BaselineSnapshot` has many `BaselineSnapshotItem` records, including `intuneRoleDefinition` items when selected. - A `Tenant` has many `InventoryItem` rows and many `PolicyVersion` rows for `intuneRoleDefinition`. - A `Tenant` has many baseline compare `OperationRun` rows and many `Finding` rows. - A Role Definition compare result links one baseline snapshot item to zero or one current inventory row and zero or one current `PolicyVersion`. ## Invariants - `intuneRoleDefinition` is the only RBAC foundation type eligible for baseline compare in this release. - `intuneRoleAssignment` must never appear in baseline capture, compare summaries, or findings. - Role Definition identity is ID-based; same-name recreated objects with new IDs are drift. - Compare uses normalized governance-relevant content, not raw transport payload shape. - Metadata-only changes stay distinguishable from permission changes. - Baseline evidence remains reconstructable without UI-time provider calls. - Workspace-owned baseline artifacts must not persist tenant IDs. - Tenant-owned compare runs and findings must remain workspace- and tenant-scoped. ## State Transitions ### Baseline support state - unsupported - supported and selectable in baseline profile ### Role Definition compare classification - unchanged - modified - missing - unexpected ### RBAC finding lifecycle - new - reopened - resolved - closed ### Compare trust state - full coverage proven - partial coverage proven with suppression - coverage unproven and findings suppressed ## Validation Rules - Baseline profile foundation selections must be a subset of explicitly baseline-supported foundation types. - Baseline snapshot items for `intuneRoleDefinition` must carry stable identity and evidence-ready references. - Role Definition compare must ignore transport-only noise and ordering differences in permission blocks. - Severity mapping must follow the approved RBAC rule set. - Assignment foundation type must fail closed for baseline-compare selection and result generation.