## 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
260 lines
7.8 KiB
YAML
260 lines
7.8 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: Intune RBAC Foundation Inventory and Backup Contract (127)
|
|
version: 0.1.0
|
|
description: |
|
|
Conceptual contract for how existing tenant inventory, coverage, backup, and
|
|
verification flows are extended by Intune RBAC foundation types.
|
|
|
|
NOTE: This feature reuses existing Filament and service-driven flows. The
|
|
contract documents required domain behavior, scoping, and payload shape rather
|
|
than promising new public routes.
|
|
|
|
servers:
|
|
- url: https://example.invalid
|
|
|
|
paths:
|
|
/tenants/{tenantId}/inventory-sync:
|
|
post:
|
|
summary: Run tenant inventory sync including RBAC foundations
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/InventorySelection'
|
|
responses:
|
|
'202':
|
|
description: Inventory sync accepted into the existing OperationRun flow
|
|
'404':
|
|
description: Not found for non-members or wrong tenant scope
|
|
'403':
|
|
description: Forbidden for tenant members without inventory-sync capability
|
|
|
|
/tenants/{tenantId}/inventory/coverage:
|
|
get:
|
|
summary: Read tenant inventory coverage including RBAC foundation types
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
responses:
|
|
'200':
|
|
description: Coverage payload
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/InventoryCoverage'
|
|
'404':
|
|
description: Not found for non-members or wrong tenant scope
|
|
'403':
|
|
description: Forbidden for tenant members without view capability
|
|
|
|
/tenants/{tenantId}/backup-sets:
|
|
post:
|
|
summary: Create backup set including RBAC foundations
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/BackupCreateRequest'
|
|
responses:
|
|
'202':
|
|
description: Backup capture accepted into the existing OperationRun flow
|
|
'404':
|
|
description: Not found for non-members or wrong tenant scope
|
|
'403':
|
|
description: Forbidden for tenant members without backup capability
|
|
|
|
/tenants/{tenantId}/backup-sets/{backupSetId}/items/{backupItemId}:
|
|
get:
|
|
summary: Read immutable RBAC foundation backup item detail
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
- $ref: '#/components/parameters/BackupSetId'
|
|
- $ref: '#/components/parameters/BackupItemId'
|
|
responses:
|
|
'200':
|
|
description: Backup item detail
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/FoundationBackupItem'
|
|
'404':
|
|
description: Not found for non-members or wrong tenant scope
|
|
'403':
|
|
description: Forbidden for tenant members without backup or version visibility
|
|
|
|
/tenants/{tenantId}/verification/provider-permissions/rbac:
|
|
get:
|
|
summary: Read RBAC permission readiness for inventory and backup coverage
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
responses:
|
|
'200':
|
|
description: Verification check row for RBAC read coverage
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/VerificationCheck'
|
|
'404':
|
|
description: Not found for non-members or wrong tenant scope
|
|
'403':
|
|
description: Forbidden for tenant members without verification visibility
|
|
|
|
components:
|
|
parameters:
|
|
TenantId:
|
|
name: tenantId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
BackupSetId:
|
|
name: backupSetId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
BackupItemId:
|
|
name: backupItemId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
|
|
schemas:
|
|
InventorySelection:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [policy_types, categories, include_foundations, include_dependencies]
|
|
properties:
|
|
policy_types:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Existing selected policy types; RBAC foundations are included when include_foundations is true.
|
|
categories:
|
|
type: array
|
|
items:
|
|
type: string
|
|
include_foundations:
|
|
type: boolean
|
|
default: true
|
|
include_dependencies:
|
|
type: boolean
|
|
default: true
|
|
|
|
InventoryCoverage:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [foundation_types]
|
|
properties:
|
|
foundation_types:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [intuneRoleDefinition, intuneRoleAssignment]
|
|
properties:
|
|
intuneRoleDefinition:
|
|
$ref: '#/components/schemas/CoverageRow'
|
|
intuneRoleAssignment:
|
|
$ref: '#/components/schemas/CoverageRow'
|
|
|
|
CoverageRow:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status]
|
|
properties:
|
|
status:
|
|
type: string
|
|
enum: [succeeded, failed, skipped]
|
|
item_count:
|
|
type: integer
|
|
minimum: 0
|
|
error_code:
|
|
type: string
|
|
nullable: true
|
|
|
|
BackupCreateRequest:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [include_foundations]
|
|
properties:
|
|
policy_ids:
|
|
type: array
|
|
items:
|
|
type: integer
|
|
include_assignments:
|
|
type: boolean
|
|
default: false
|
|
include_scope_tags:
|
|
type: boolean
|
|
default: false
|
|
include_foundations:
|
|
type: boolean
|
|
description: Must be true for RBAC foundation capture.
|
|
|
|
FoundationBackupItem:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [policy_type, policy_identifier, payload, metadata, restore_mode]
|
|
properties:
|
|
policy_id:
|
|
type: integer
|
|
nullable: true
|
|
description: Synthetic tenant-scoped policy anchor used for immutable RBAC history when version linkage is available.
|
|
policy_version_id:
|
|
type: integer
|
|
nullable: true
|
|
description: Immutable version row for RBAC foundation snapshots; present for role definitions and role assignments.
|
|
policy_type:
|
|
type: string
|
|
enum: [intuneRoleDefinition, intuneRoleAssignment]
|
|
policy_identifier:
|
|
type: string
|
|
display_name:
|
|
type: string
|
|
nullable: true
|
|
payload:
|
|
type: object
|
|
description: Immutable captured Graph payload.
|
|
metadata:
|
|
type: object
|
|
description: Snapshot metadata carried on the backup item; readable display attributes remain immutable even if the synthetic anchor changes later.
|
|
restore_mode:
|
|
type: string
|
|
enum: [preview-only]
|
|
|
|
VerificationCheck:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [key, status, severity, blocking, reason_code, message]
|
|
properties:
|
|
key:
|
|
type: string
|
|
example: intune_rbac_permissions
|
|
status:
|
|
type: string
|
|
enum: [pass, warn, fail, skip, running]
|
|
severity:
|
|
type: string
|
|
enum: [info, low, medium, high, critical]
|
|
blocking:
|
|
type: boolean
|
|
reason_code:
|
|
type: string
|
|
example: provider_permission_missing
|
|
message:
|
|
type: string
|
|
evidence:
|
|
type: array
|
|
items:
|
|
type: object
|
|
next_steps:
|
|
type: array
|
|
items:
|
|
type: string
|