Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 3m45s
Implemented the first version of review output resolve actions. Included a ReviewOutputResolveActionMapper, commands to seed browser fixtures, updated CustomerReviewWorkspace, EnvironmentReviewResource, UI enforcement, and related views. Also added extensive unit, feature, and browser tests, and updated the design coverage matrix.
883 lines
42 KiB
PHP
883 lines
42 KiB
PHP
<?php
|
|
|
|
return [
|
|
'break_glass' => [
|
|
'enabled' => (bool) env('BREAK_GLASS_ENABLED', false),
|
|
'ttl_minutes' => (int) env('BREAK_GLASS_TTL_MINUTES', 15),
|
|
],
|
|
|
|
'support_access' => [
|
|
'max_ttl_minutes' => (int) env('TENANTPILOT_SUPPORT_ACCESS_MAX_TTL_MINUTES', 240),
|
|
],
|
|
|
|
'system_console' => [
|
|
'stuck_thresholds' => [
|
|
'queued_minutes' => (int) env('TENANTPILOT_SYSTEM_CONSOLE_STUCK_QUEUED_MINUTES', 15),
|
|
'running_minutes' => (int) env('TENANTPILOT_SYSTEM_CONSOLE_STUCK_RUNNING_MINUTES', 30),
|
|
],
|
|
],
|
|
|
|
'operations' => [
|
|
'lifecycle' => [
|
|
'reconciliation' => [
|
|
'batch_limit' => (int) env('TENANTPILOT_OPERATION_RUN_RECONCILIATION_BATCH_LIMIT', 100),
|
|
'schedule_minutes' => (int) env('TENANTPILOT_OPERATION_RUN_RECONCILIATION_SCHEDULE_MINUTES', 5),
|
|
],
|
|
'covered_types' => [
|
|
'baseline.capture' => [
|
|
'job_class' => \App\Jobs\CaptureBaselineSnapshotJob::class,
|
|
'queued_stale_after_seconds' => 600,
|
|
'running_stale_after_seconds' => 1800,
|
|
'expected_max_runtime_seconds' => 300,
|
|
'direct_failed_bridge' => true,
|
|
'scheduled_reconciliation' => true,
|
|
],
|
|
'baseline.compare' => [
|
|
'job_class' => \App\Jobs\CompareBaselineToTenantJob::class,
|
|
'queued_stale_after_seconds' => 600,
|
|
'running_stale_after_seconds' => 1800,
|
|
'expected_max_runtime_seconds' => 300,
|
|
'direct_failed_bridge' => true,
|
|
'scheduled_reconciliation' => true,
|
|
],
|
|
'inventory.sync' => [
|
|
'job_class' => \App\Jobs\RunInventorySyncJob::class,
|
|
'queued_stale_after_seconds' => 300,
|
|
'running_stale_after_seconds' => 1200,
|
|
'expected_max_runtime_seconds' => 240,
|
|
'direct_failed_bridge' => true,
|
|
'scheduled_reconciliation' => true,
|
|
],
|
|
'policy.sync' => [
|
|
'job_class' => \App\Jobs\SyncPoliciesJob::class,
|
|
'queued_stale_after_seconds' => 300,
|
|
'running_stale_after_seconds' => 900,
|
|
'expected_max_runtime_seconds' => 180,
|
|
'direct_failed_bridge' => true,
|
|
'scheduled_reconciliation' => true,
|
|
],
|
|
'directory.groups.sync' => [
|
|
'job_class' => \App\Jobs\EntraGroupSyncJob::class,
|
|
'queued_stale_after_seconds' => 300,
|
|
'running_stale_after_seconds' => 900,
|
|
'expected_max_runtime_seconds' => 240,
|
|
'direct_failed_bridge' => false,
|
|
'scheduled_reconciliation' => true,
|
|
],
|
|
'directory.role_definitions.sync' => [
|
|
'job_class' => \App\Jobs\SyncRoleDefinitionsJob::class,
|
|
'queued_stale_after_seconds' => 300,
|
|
'running_stale_after_seconds' => 900,
|
|
'expected_max_runtime_seconds' => 240,
|
|
'direct_failed_bridge' => false,
|
|
'scheduled_reconciliation' => true,
|
|
],
|
|
'backup_set.update' => [
|
|
'job_class' => \App\Jobs\AddPoliciesToBackupSetJob::class,
|
|
'queued_stale_after_seconds' => 300,
|
|
'running_stale_after_seconds' => 900,
|
|
'expected_max_runtime_seconds' => 240,
|
|
'direct_failed_bridge' => false,
|
|
'scheduled_reconciliation' => true,
|
|
],
|
|
'backup.schedule.execute' => [
|
|
'job_class' => \App\Jobs\RunBackupScheduleJob::class,
|
|
'queued_stale_after_seconds' => 300,
|
|
'running_stale_after_seconds' => 1200,
|
|
'expected_max_runtime_seconds' => 300,
|
|
'direct_failed_bridge' => false,
|
|
'scheduled_reconciliation' => true,
|
|
],
|
|
'restore.execute' => [
|
|
'job_class' => \App\Jobs\ExecuteRestoreRunJob::class,
|
|
'queued_stale_after_seconds' => 300,
|
|
'running_stale_after_seconds' => 1500,
|
|
'expected_max_runtime_seconds' => 420,
|
|
'direct_failed_bridge' => false,
|
|
'scheduled_reconciliation' => true,
|
|
],
|
|
'promotion.execute' => [
|
|
'job_class' => \App\Jobs\Operations\CrossEnvironmentPromotionExecutionJob::class,
|
|
'queued_stale_after_seconds' => 300,
|
|
'running_stale_after_seconds' => 1500,
|
|
'expected_max_runtime_seconds' => 420,
|
|
'direct_failed_bridge' => false,
|
|
'scheduled_reconciliation' => true,
|
|
],
|
|
'environment.review_pack.generate' => [
|
|
'job_class' => \App\Jobs\GenerateReviewPackJob::class,
|
|
'queued_stale_after_seconds' => 300,
|
|
'running_stale_after_seconds' => 900,
|
|
'expected_max_runtime_seconds' => 240,
|
|
'direct_failed_bridge' => false,
|
|
'scheduled_reconciliation' => true,
|
|
],
|
|
'environment.review.compose' => [
|
|
'job_class' => \App\Jobs\ComposeEnvironmentReviewJob::class,
|
|
'queued_stale_after_seconds' => 300,
|
|
'running_stale_after_seconds' => 900,
|
|
'expected_max_runtime_seconds' => 240,
|
|
'direct_failed_bridge' => true,
|
|
'scheduled_reconciliation' => true,
|
|
],
|
|
'tenant.evidence.snapshot.generate' => [
|
|
'job_class' => \App\Jobs\GenerateEvidenceSnapshotJob::class,
|
|
'queued_stale_after_seconds' => 300,
|
|
'running_stale_after_seconds' => 900,
|
|
'expected_max_runtime_seconds' => 240,
|
|
'direct_failed_bridge' => false,
|
|
'scheduled_reconciliation' => true,
|
|
],
|
|
],
|
|
],
|
|
],
|
|
|
|
'backup_health' => [
|
|
'freshness_hours' => (int) env('TENANTPILOT_BACKUP_HEALTH_FRESHNESS_HOURS', 24),
|
|
'schedule_overdue_grace_minutes' => (int) env('TENANTPILOT_BACKUP_HEALTH_SCHEDULE_OVERDUE_GRACE_MINUTES', 30),
|
|
'browser_smoke_fixture' => [
|
|
'workspace' => [
|
|
'name' => env('TENANTPILOT_BACKUP_HEALTH_SMOKE_WORKSPACE_NAME', 'Spec 180 Backup Health Smoke'),
|
|
'slug' => env('TENANTPILOT_BACKUP_HEALTH_SMOKE_WORKSPACE_SLUG', 'spec-180-backup-health-smoke'),
|
|
],
|
|
'user' => [
|
|
'name' => env('TENANTPILOT_BACKUP_HEALTH_SMOKE_USER_NAME', 'Spec 180 Requester'),
|
|
'email' => env('TENANTPILOT_BACKUP_HEALTH_SMOKE_USER_EMAIL', 'smoke-requester+180@tenantpilot.local'),
|
|
'password' => env('TENANTPILOT_BACKUP_HEALTH_SMOKE_USER_PASSWORD', 'password'),
|
|
],
|
|
'blocked_drillthrough' => [
|
|
'tenant_name' => env('TENANTPILOT_BACKUP_HEALTH_SMOKE_TENANT_NAME', 'Spec 180 Blocked Backup Tenant'),
|
|
'tenant_external_id' => env('TENANTPILOT_BACKUP_HEALTH_SMOKE_TENANT_EXTERNAL_ID', '18000000-0000-4000-8000-000000000180'),
|
|
'tenant_id' => env('TENANTPILOT_BACKUP_HEALTH_SMOKE_TENANT_ID', '18000000-0000-4000-8000-000000000180'),
|
|
'app_client_id' => env('TENANTPILOT_BACKUP_HEALTH_SMOKE_APP_CLIENT_ID', '18000000-0000-4000-8000-000000000182'),
|
|
'policy_external_id' => env('TENANTPILOT_BACKUP_HEALTH_SMOKE_POLICY_EXTERNAL_ID', 'spec-180-rbac-stale-policy'),
|
|
'policy_type' => env('TENANTPILOT_BACKUP_HEALTH_SMOKE_POLICY_TYPE', 'settingsCatalogPolicy'),
|
|
'policy_name' => env('TENANTPILOT_BACKUP_HEALTH_SMOKE_POLICY_NAME', 'Spec 180 RBAC Smoke Policy'),
|
|
'backup_set_name' => env('TENANTPILOT_BACKUP_HEALTH_SMOKE_BACKUP_SET_NAME', 'Spec 180 Blocked Stale Backup'),
|
|
'stale_age_hours' => (int) env('TENANTPILOT_BACKUP_HEALTH_SMOKE_STALE_AGE_HOURS', 48),
|
|
'capability_denials' => [
|
|
\App\Support\Auth\Capabilities::TENANT_VIEW,
|
|
],
|
|
],
|
|
],
|
|
],
|
|
|
|
'review_output' => [
|
|
'browser_smoke_fixture' => [
|
|
'workspace' => [
|
|
'name' => 'Spec 351 Review Output Smoke',
|
|
'slug' => 'spec-351-review-output-smoke',
|
|
],
|
|
'user' => [
|
|
'name' => 'Spec 351 Requester',
|
|
'email' => 'smoke-requester+351@tenantpilot.local',
|
|
'password' => 'password',
|
|
],
|
|
'ready_draft' => [
|
|
'managed_environment_name' => 'Spec 351 Browser Ready Draft',
|
|
'managed_environment_slug' => 'spec-351-browser-ready-draft',
|
|
'operation_initiator_name' => 'Spec 351 Browser Operator',
|
|
'publish_reason' => 'Seed published predecessor for Spec 351 browser verification.',
|
|
'published_review_pack_path' => 'review-packs/spec351-browser-ready-published.zip',
|
|
'published_review_pack_contents' => 'PK-spec351-browser-ready-published',
|
|
],
|
|
],
|
|
],
|
|
|
|
'supported_policy_types' => [
|
|
[
|
|
'type' => 'deviceConfiguration',
|
|
'label' => 'Device Configuration',
|
|
'category' => 'Configuration',
|
|
'platform' => 'all',
|
|
'endpoint' => 'deviceManagement/deviceConfigurations',
|
|
'filter' => "not isof('microsoft.graph.windowsUpdateForBusinessConfiguration')",
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'medium',
|
|
],
|
|
[
|
|
'type' => 'groupPolicyConfiguration',
|
|
'label' => 'Administrative Templates',
|
|
'category' => 'Configuration',
|
|
'platform' => 'windows',
|
|
'endpoint' => 'deviceManagement/groupPolicyConfigurations',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'medium',
|
|
],
|
|
[
|
|
'type' => 'settingsCatalogPolicy',
|
|
'label' => 'Settings Catalog Policy',
|
|
'category' => 'Configuration',
|
|
'platform' => 'windows',
|
|
'endpoint' => 'deviceManagement/configurationPolicies',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'medium',
|
|
],
|
|
[
|
|
'type' => 'windowsUpdateRing',
|
|
'label' => 'Software Update Ring',
|
|
'category' => 'Update Management',
|
|
'platform' => 'windows',
|
|
'endpoint' => 'deviceManagement/deviceConfigurations',
|
|
'filter' => "isof('microsoft.graph.windowsUpdateForBusinessConfiguration')",
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'medium-high',
|
|
],
|
|
[
|
|
'type' => 'windowsFeatureUpdateProfile',
|
|
'label' => 'Feature Updates (Windows)',
|
|
'category' => 'Update Management',
|
|
'platform' => 'windows',
|
|
'endpoint' => 'deviceManagement/windowsFeatureUpdateProfiles',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'high',
|
|
],
|
|
[
|
|
'type' => 'windowsQualityUpdateProfile',
|
|
'label' => 'Quality Updates (Windows)',
|
|
'category' => 'Update Management',
|
|
'platform' => 'windows',
|
|
'endpoint' => 'deviceManagement/windowsQualityUpdateProfiles',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'high',
|
|
],
|
|
[
|
|
'type' => 'windowsDriverUpdateProfile',
|
|
'label' => 'Driver Updates (Windows)',
|
|
'category' => 'Update Management',
|
|
'platform' => 'windows',
|
|
'endpoint' => 'deviceManagement/windowsDriverUpdateProfiles',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'high',
|
|
],
|
|
[
|
|
'type' => 'deviceCompliancePolicy',
|
|
'label' => 'Device Compliance',
|
|
'category' => 'Compliance',
|
|
'platform' => 'all',
|
|
'endpoint' => 'deviceManagement/deviceCompliancePolicies',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'medium',
|
|
],
|
|
[
|
|
'type' => 'appProtectionPolicy',
|
|
'label' => 'App Protection (MAM)',
|
|
'category' => 'Apps/MAM',
|
|
'platform' => 'mobile',
|
|
'endpoint' => 'deviceAppManagement/managedAppPolicies',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'medium-high',
|
|
],
|
|
[
|
|
'type' => 'mamAppConfiguration',
|
|
'label' => 'App Configuration (MAM)',
|
|
'category' => 'Apps/MAM',
|
|
'platform' => 'mobile',
|
|
'endpoint' => 'deviceAppManagement/targetedManagedAppConfigurations',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'medium-high',
|
|
],
|
|
[
|
|
'type' => 'managedDeviceAppConfiguration',
|
|
'label' => 'App Configuration (Device)',
|
|
'category' => 'Apps/MAM',
|
|
'platform' => 'mobile',
|
|
'endpoint' => 'deviceAppManagement/mobileAppConfigurations',
|
|
'filter' => "microsoft.graph.androidManagedStoreAppConfiguration/appSupportsOemConfig eq false or isof('microsoft.graph.androidManagedStoreAppConfiguration') eq false",
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'medium-high',
|
|
],
|
|
[
|
|
'type' => 'conditionalAccessPolicy',
|
|
'label' => 'Conditional Access',
|
|
'category' => 'Conditional Access',
|
|
'platform' => 'all',
|
|
'endpoint' => 'identity/conditionalAccess/policies',
|
|
'backup' => 'full',
|
|
'restore' => 'preview-only',
|
|
'risk' => 'high',
|
|
],
|
|
[
|
|
'type' => 'deviceManagementScript',
|
|
'label' => 'PowerShell Scripts',
|
|
'category' => 'Scripts',
|
|
'platform' => 'windows',
|
|
'endpoint' => 'deviceManagement/deviceManagementScripts',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'medium',
|
|
],
|
|
[
|
|
'type' => 'deviceShellScript',
|
|
'label' => 'macOS Shell Scripts',
|
|
'category' => 'Scripts',
|
|
'platform' => 'macOS',
|
|
'endpoint' => 'deviceManagement/deviceShellScripts',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'medium',
|
|
],
|
|
[
|
|
'type' => 'deviceHealthScript',
|
|
'label' => 'Proactive Remediations',
|
|
'category' => 'Scripts',
|
|
'platform' => 'windows',
|
|
'endpoint' => 'deviceManagement/deviceHealthScripts',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'medium',
|
|
],
|
|
[
|
|
'type' => 'deviceComplianceScript',
|
|
'label' => 'Custom Compliance Scripts',
|
|
'category' => 'Compliance',
|
|
'platform' => 'windows',
|
|
'endpoint' => 'deviceManagement/deviceComplianceScripts',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'medium-high',
|
|
],
|
|
[
|
|
'type' => 'windowsAutopilotDeploymentProfile',
|
|
'label' => 'Windows Autopilot Profiles',
|
|
'category' => 'Autopilot',
|
|
'platform' => 'windows',
|
|
'endpoint' => 'deviceManagement/windowsAutopilotDeploymentProfiles',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'medium-high',
|
|
],
|
|
[
|
|
'type' => 'windowsEnrollmentStatusPage',
|
|
'label' => 'Enrollment Status Page (ESP)',
|
|
'category' => 'Enrollment',
|
|
'platform' => 'all',
|
|
'endpoint' => 'deviceManagement/deviceEnrollmentConfigurations',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'medium',
|
|
],
|
|
[
|
|
'type' => 'deviceEnrollmentLimitConfiguration',
|
|
'label' => 'Enrollment Limits',
|
|
'category' => 'Enrollment',
|
|
'platform' => 'all',
|
|
'endpoint' => 'deviceManagement/deviceEnrollmentConfigurations',
|
|
'backup' => 'full',
|
|
'restore' => 'preview-only',
|
|
'risk' => 'high',
|
|
],
|
|
[
|
|
'type' => 'deviceEnrollmentPlatformRestrictionsConfiguration',
|
|
'label' => 'Platform Restrictions (Enrollment)',
|
|
'category' => 'Enrollment',
|
|
'platform' => 'all',
|
|
'endpoint' => 'deviceManagement/deviceEnrollmentConfigurations',
|
|
'backup' => 'full',
|
|
'restore' => 'preview-only',
|
|
'risk' => 'high',
|
|
],
|
|
[
|
|
'type' => 'deviceEnrollmentNotificationConfiguration',
|
|
'label' => 'Enrollment Notifications',
|
|
'category' => 'Enrollment',
|
|
'platform' => 'all',
|
|
'endpoint' => 'deviceManagement/deviceEnrollmentConfigurations',
|
|
'filter' => "deviceEnrollmentConfigurationType eq 'EnrollmentNotificationsConfiguration'",
|
|
'backup' => 'full',
|
|
'restore' => 'preview-only',
|
|
'risk' => 'high',
|
|
],
|
|
[
|
|
'type' => 'enrollmentRestriction',
|
|
'label' => 'Enrollment Restrictions',
|
|
'category' => 'Enrollment',
|
|
'platform' => 'all',
|
|
'endpoint' => 'deviceManagement/deviceEnrollmentConfigurations',
|
|
'backup' => 'full',
|
|
'restore' => 'preview-only',
|
|
'risk' => 'high',
|
|
],
|
|
[
|
|
'type' => 'termsAndConditions',
|
|
'label' => 'Terms & Conditions',
|
|
'category' => 'Enrollment',
|
|
'platform' => 'all',
|
|
'endpoint' => 'deviceManagement/termsAndConditions',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'medium-high',
|
|
],
|
|
[
|
|
'type' => 'endpointSecurityIntent',
|
|
'label' => 'Endpoint Security Intents',
|
|
'category' => 'Endpoint Security',
|
|
'platform' => 'windows',
|
|
'endpoint' => 'deviceManagement/intents',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'high',
|
|
],
|
|
[
|
|
'type' => 'endpointSecurityPolicy',
|
|
'label' => 'Endpoint Security Policies',
|
|
'category' => 'Endpoint Security',
|
|
'platform' => 'windows',
|
|
'endpoint' => 'deviceManagement/configurationPolicies',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'high',
|
|
],
|
|
[
|
|
'type' => 'securityBaselinePolicy',
|
|
'label' => 'Security Baselines',
|
|
'category' => 'Endpoint Security',
|
|
'platform' => 'windows',
|
|
'endpoint' => 'deviceManagement/configurationPolicies',
|
|
'backup' => 'full',
|
|
'restore' => 'preview-only',
|
|
'risk' => 'high',
|
|
],
|
|
[
|
|
'type' => 'mobileApp',
|
|
'label' => 'Applications (Metadata only)',
|
|
'category' => 'Applications',
|
|
'platform' => 'all',
|
|
'endpoint' => 'deviceAppManagement/mobileApps',
|
|
'backup' => 'metadata-only',
|
|
'restore' => 'enabled',
|
|
'risk' => 'low-medium',
|
|
],
|
|
],
|
|
|
|
'foundation_types' => [
|
|
[
|
|
'type' => 'assignmentFilter',
|
|
'label' => 'Assignment Filter',
|
|
'category' => 'Foundations',
|
|
'platform' => 'all',
|
|
'endpoint' => 'deviceManagement/assignmentFilters',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'low',
|
|
'baseline_compare' => [
|
|
'supported' => true,
|
|
'identity_strategy' => 'display_name',
|
|
'resolution' => [
|
|
'subject_class' => 'foundation_backed',
|
|
'resolution_path' => 'foundation_inventory',
|
|
'compare_capability' => 'limited',
|
|
'capture_capability' => 'limited',
|
|
'source_model_expected' => 'inventory',
|
|
],
|
|
],
|
|
],
|
|
[
|
|
'type' => 'roleScopeTag',
|
|
'label' => 'Scope Tag',
|
|
'category' => 'Foundations',
|
|
'platform' => 'all',
|
|
'endpoint' => 'deviceManagement/roleScopeTags',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'low',
|
|
'baseline_compare' => [
|
|
'supported' => true,
|
|
'identity_strategy' => 'display_name',
|
|
'resolution' => [
|
|
'subject_class' => 'foundation_backed',
|
|
'resolution_path' => 'foundation_inventory',
|
|
'compare_capability' => 'limited',
|
|
'capture_capability' => 'limited',
|
|
'source_model_expected' => 'inventory',
|
|
],
|
|
],
|
|
],
|
|
[
|
|
'type' => 'intuneRoleDefinition',
|
|
'label' => 'Intune RBAC Role Definition',
|
|
'category' => 'RBAC',
|
|
'platform' => 'all',
|
|
'endpoint' => 'deviceManagement/roleDefinitions',
|
|
'backup' => 'full',
|
|
'restore' => 'preview-only',
|
|
'risk' => 'high',
|
|
'baseline_compare' => [
|
|
'supported' => true,
|
|
'identity_strategy' => 'external_id',
|
|
'resolution' => [
|
|
'subject_class' => 'foundation_backed',
|
|
'resolution_path' => 'foundation_policy',
|
|
'compare_capability' => 'supported',
|
|
'capture_capability' => 'supported',
|
|
'source_model_expected' => 'policy',
|
|
],
|
|
],
|
|
],
|
|
[
|
|
'type' => 'intuneRoleAssignment',
|
|
'label' => 'Intune RBAC Role Assignment',
|
|
'category' => 'RBAC',
|
|
'platform' => 'all',
|
|
'endpoint' => 'deviceManagement/roleAssignments',
|
|
'backup' => 'full',
|
|
'restore' => 'preview-only',
|
|
'risk' => 'high',
|
|
'baseline_compare' => [
|
|
'supported' => false,
|
|
'identity_strategy' => 'external_id',
|
|
'resolution' => [
|
|
'subject_class' => 'foundation_backed',
|
|
'resolution_path' => 'foundation_policy',
|
|
'compare_capability' => 'unsupported',
|
|
'capture_capability' => 'unsupported',
|
|
'source_model_expected' => 'policy',
|
|
],
|
|
],
|
|
],
|
|
[
|
|
'type' => 'notificationMessageTemplate',
|
|
'label' => 'Notification Message Template',
|
|
'category' => 'Foundations',
|
|
'platform' => 'all',
|
|
'endpoint' => 'deviceManagement/notificationMessageTemplates',
|
|
'backup' => 'full',
|
|
'restore' => 'enabled',
|
|
'risk' => 'low',
|
|
'baseline_compare' => [
|
|
'supported' => true,
|
|
'identity_strategy' => 'display_name',
|
|
'resolution' => [
|
|
'subject_class' => 'foundation_backed',
|
|
'resolution_path' => 'foundation_inventory',
|
|
'compare_capability' => 'limited',
|
|
'capture_capability' => 'limited',
|
|
'source_model_expected' => 'inventory',
|
|
],
|
|
],
|
|
],
|
|
],
|
|
|
|
'features' => [
|
|
'conditional_access' => true,
|
|
],
|
|
|
|
'bulk_operations' => [
|
|
'chunk_size' => (int) env('TENANTPILOT_BULK_CHUNK_SIZE', 10),
|
|
'poll_interval_seconds' => (int) env('TENANTPILOT_BULK_POLL_INTERVAL_SECONDS', 3),
|
|
'recent_finished_seconds' => (int) env('TENANTPILOT_BULK_RECENT_FINISHED_SECONDS', 12),
|
|
'progress_widget_enabled' => (bool) env('TENANTPILOT_BULK_PROGRESS_WIDGET_ENABLED', true),
|
|
'concurrency' => [
|
|
'per_target_scope_max' => (int) env('TENANTPILOT_BULK_CONCURRENCY_PER_TARGET_SCOPE_MAX', 1),
|
|
'lock_ttl_seconds' => (int) env('TENANTPILOT_BULK_CONCURRENCY_LOCK_TTL_SECONDS', 900),
|
|
],
|
|
],
|
|
|
|
'inventory_sync' => [
|
|
'concurrency' => [
|
|
'global_max' => (int) env('TENANTPILOT_INVENTORY_SYNC_CONCURRENCY_GLOBAL_MAX', 2),
|
|
'per_tenant_max' => (int) env('TENANTPILOT_INVENTORY_SYNC_CONCURRENCY_PER_TENANT_MAX', 1),
|
|
],
|
|
],
|
|
|
|
'alerts' => [
|
|
'enabled' => (bool) env('TENANTPILOT_ALERTS_ENABLED', true),
|
|
'evaluate_initial_lookback_minutes' => (int) env('TENANTPILOT_ALERTS_EVALUATE_INITIAL_LOOKBACK_MINUTES', 15),
|
|
'delivery_retention_days' => (int) env('TENANTPILOT_ALERTS_DELIVERY_RETENTION_DAYS', 90),
|
|
'delivery_max_attempts' => (int) env('TENANTPILOT_ALERTS_DELIVERY_MAX_ATTEMPTS', 3),
|
|
'delivery_retry_base_seconds' => (int) env('TENANTPILOT_ALERTS_DELIVERY_RETRY_BASE_SECONDS', 60),
|
|
'delivery_retry_max_seconds' => (int) env('TENANTPILOT_ALERTS_DELIVERY_RETRY_MAX_SECONDS', 900),
|
|
'deliver_batch_size' => (int) env('TENANTPILOT_ALERTS_DELIVER_BATCH_SIZE', 200),
|
|
'http_timeout_seconds' => (int) env('TENANTPILOT_ALERTS_HTTP_TIMEOUT_SECONDS', 10),
|
|
],
|
|
|
|
'stored_reports' => [
|
|
'retention_days' => (int) env('TENANTPILOT_STORED_REPORTS_RETENTION_DAYS', 90),
|
|
],
|
|
|
|
'product_usage_event_retention_days' => (int) env('TENANTPILOT_PRODUCT_USAGE_EVENT_RETENTION_DAYS', 90),
|
|
|
|
'display' => [
|
|
'show_script_content' => (bool) env('TENANTPILOT_SHOW_SCRIPT_CONTENT', false),
|
|
'max_script_content_chars' => (int) env('TENANTPILOT_MAX_SCRIPT_CONTENT_CHARS', 5000),
|
|
],
|
|
|
|
'review_pack' => [
|
|
'retention_days' => (int) env('TENANTPILOT_REVIEW_PACK_RETENTION_DAYS', 90),
|
|
'hard_delete_grace_days' => (int) env('TENANTPILOT_REVIEW_PACK_HARD_DELETE_GRACE_DAYS', 30),
|
|
'download_url_ttl_minutes' => (int) env('TENANTPILOT_REVIEW_PACK_DOWNLOAD_URL_TTL_MINUTES', 60),
|
|
'include_pii_default' => (bool) env('TENANTPILOT_REVIEW_PACK_INCLUDE_PII_DEFAULT', true),
|
|
'include_operations_default' => (bool) env('TENANTPILOT_REVIEW_PACK_INCLUDE_OPERATIONS_DEFAULT', true),
|
|
],
|
|
|
|
'baselines' => [
|
|
'full_content_capture' => [
|
|
'enabled' => (bool) env('TENANTPILOT_BASELINE_FULL_CONTENT_CAPTURE_ENABLED', false),
|
|
'max_items_per_run' => (int) env('TENANTPILOT_BASELINE_EVIDENCE_MAX_ITEMS_PER_RUN', 200),
|
|
'max_concurrency' => (int) env('TENANTPILOT_BASELINE_EVIDENCE_MAX_CONCURRENCY', 5),
|
|
'max_retries' => (int) env('TENANTPILOT_BASELINE_EVIDENCE_MAX_RETRIES', 3),
|
|
'retention_days' => (int) env('TENANTPILOT_BASELINE_EVIDENCE_RETENTION_DAYS', 90),
|
|
],
|
|
],
|
|
|
|
'platform_vocabulary' => [
|
|
'terms' => [
|
|
'governed_subject' => [
|
|
'term_key' => 'governed_subject',
|
|
'canonical_label' => 'Governed subject',
|
|
'canonical_description' => 'The platform-facing noun for a governed object across compare, snapshot, evidence, and review surfaces.',
|
|
'boundary_classification' => 'platform_core',
|
|
'owner_layer' => 'platform_core',
|
|
'allowed_contexts' => ['compare', 'snapshot', 'evidence', 'review', 'reporting'],
|
|
'legacy_aliases' => ['policy_type'],
|
|
'alias_retirement_path' => 'Retire false-universal policy_type wording from platform-owned summaries and descriptors while preserving Intune-owned storage.',
|
|
'forbidden_platform_aliases' => ['policy_type'],
|
|
],
|
|
'domain_key' => [
|
|
'term_key' => 'domain_key',
|
|
'canonical_label' => 'Governance domain',
|
|
'canonical_description' => 'The canonical domain discriminator for cross-domain and platform-near contracts.',
|
|
'boundary_classification' => 'cross_domain_governance',
|
|
'owner_layer' => 'platform_core',
|
|
'allowed_contexts' => ['governance', 'compare', 'snapshot', 'reporting'],
|
|
'legacy_aliases' => [],
|
|
'alias_retirement_path' => null,
|
|
'forbidden_platform_aliases' => [],
|
|
],
|
|
'subject_class' => [
|
|
'term_key' => 'subject_class',
|
|
'canonical_label' => 'Subject class',
|
|
'canonical_description' => 'The canonical subject-class discriminator for governed-subject contracts.',
|
|
'boundary_classification' => 'cross_domain_governance',
|
|
'owner_layer' => 'platform_core',
|
|
'allowed_contexts' => ['governance', 'compare', 'snapshot'],
|
|
'legacy_aliases' => [],
|
|
'alias_retirement_path' => null,
|
|
'forbidden_platform_aliases' => [],
|
|
],
|
|
'subject_type_key' => [
|
|
'term_key' => 'subject_type_key',
|
|
'canonical_label' => 'Governed subject key',
|
|
'canonical_description' => 'The domain-owned subject-family key used by platform-near descriptors.',
|
|
'boundary_classification' => 'cross_domain_governance',
|
|
'owner_layer' => 'platform_core',
|
|
'allowed_contexts' => ['governance', 'compare', 'snapshot', 'evidence'],
|
|
'legacy_aliases' => ['policy_type'],
|
|
'alias_retirement_path' => 'Prefer subject_type_key on platform-near payloads and keep policy_type only where the owning model is Intune-specific.',
|
|
'forbidden_platform_aliases' => ['policy_type'],
|
|
],
|
|
'subject_type_label' => [
|
|
'term_key' => 'subject_type_label',
|
|
'canonical_label' => 'Governed subject label',
|
|
'canonical_description' => 'The operator-facing label for a governed subject family.',
|
|
'boundary_classification' => 'cross_domain_governance',
|
|
'owner_layer' => 'platform_core',
|
|
'allowed_contexts' => ['snapshot', 'evidence', 'compare', 'review'],
|
|
'legacy_aliases' => [],
|
|
'alias_retirement_path' => null,
|
|
'forbidden_platform_aliases' => [],
|
|
],
|
|
'resource_type' => [
|
|
'term_key' => 'resource_type',
|
|
'canonical_label' => 'Resource type',
|
|
'canonical_description' => 'Optional resource-shaped noun for platform-facing summaries when a governed subject also needs a resource family label.',
|
|
'boundary_classification' => 'platform_core',
|
|
'owner_layer' => 'platform_core',
|
|
'allowed_contexts' => ['reporting', 'review'],
|
|
'legacy_aliases' => [],
|
|
'alias_retirement_path' => null,
|
|
'forbidden_platform_aliases' => [],
|
|
],
|
|
'operation_type' => [
|
|
'term_key' => 'operation_type',
|
|
'canonical_label' => 'Operation type',
|
|
'canonical_description' => 'The canonical platform operation identifier shown on monitoring and launch surfaces.',
|
|
'boundary_classification' => 'platform_core',
|
|
'owner_layer' => 'platform_core',
|
|
'allowed_contexts' => ['monitoring', 'reporting', 'launch_surfaces'],
|
|
'legacy_aliases' => ['type'],
|
|
'alias_retirement_path' => 'Expose canonical operation_type on read models while operation_runs.type remains a compatibility storage seam during rollout.',
|
|
'forbidden_platform_aliases' => [],
|
|
],
|
|
'platform_reason_family' => [
|
|
'term_key' => 'platform_reason_family',
|
|
'canonical_label' => 'Platform reason family',
|
|
'canonical_description' => 'The cross-domain platform family that explains the top-level cause category without erasing domain ownership.',
|
|
'boundary_classification' => 'platform_core',
|
|
'owner_layer' => 'platform_core',
|
|
'allowed_contexts' => ['reason_translation', 'monitoring', 'review', 'reporting'],
|
|
'legacy_aliases' => [],
|
|
'alias_retirement_path' => null,
|
|
'forbidden_platform_aliases' => [],
|
|
],
|
|
'reason_owner.owner_namespace' => [
|
|
'term_key' => 'reason_owner.owner_namespace',
|
|
'canonical_label' => 'Reason owner namespace',
|
|
'canonical_description' => 'The explicit namespace that marks whether a translated reason is provider-owned, governance-owned, access-owned, or runtime-owned.',
|
|
'boundary_classification' => 'platform_core',
|
|
'owner_layer' => 'platform_core',
|
|
'allowed_contexts' => ['reason_translation', 'review', 'reporting'],
|
|
'legacy_aliases' => [],
|
|
'alias_retirement_path' => null,
|
|
'forbidden_platform_aliases' => [],
|
|
],
|
|
'reason_code' => [
|
|
'term_key' => 'reason_code',
|
|
'canonical_label' => 'Reason code',
|
|
'canonical_description' => 'The original domain-owned or provider-owned reason identifier preserved for diagnostics and translation lookup.',
|
|
'boundary_classification' => 'platform_core',
|
|
'owner_layer' => 'platform_core',
|
|
'allowed_contexts' => ['reason_translation', 'diagnostics'],
|
|
'legacy_aliases' => [],
|
|
'alias_retirement_path' => null,
|
|
'forbidden_platform_aliases' => [],
|
|
],
|
|
'registry_key' => [
|
|
'term_key' => 'registry_key',
|
|
'canonical_label' => 'Registry key',
|
|
'canonical_description' => 'The stable identifier for a contributor-facing registry or catalog.',
|
|
'boundary_classification' => 'platform_core',
|
|
'owner_layer' => 'platform_core',
|
|
'allowed_contexts' => ['governance', 'contributor_guidance'],
|
|
'legacy_aliases' => [],
|
|
'alias_retirement_path' => null,
|
|
'forbidden_platform_aliases' => [],
|
|
],
|
|
'boundary_classification' => [
|
|
'term_key' => 'boundary_classification',
|
|
'canonical_label' => 'Boundary classification',
|
|
'canonical_description' => 'The explicit classification that marks a term or registry as platform_core, cross_domain_governance, or intune_specific.',
|
|
'boundary_classification' => 'platform_core',
|
|
'owner_layer' => 'platform_core',
|
|
'allowed_contexts' => ['governance', 'contributor_guidance'],
|
|
'legacy_aliases' => [],
|
|
'alias_retirement_path' => null,
|
|
'forbidden_platform_aliases' => [],
|
|
],
|
|
'policy_type' => [
|
|
'term_key' => 'policy_type',
|
|
'canonical_label' => 'Intune policy type',
|
|
'canonical_description' => 'The Intune-specific discriminator that remains valid on adapter-owned or Intune-owned models but must not be treated as a universal platform noun.',
|
|
'boundary_classification' => 'intune_specific',
|
|
'owner_layer' => 'domain_owned',
|
|
'allowed_contexts' => ['intune_adapter', 'intune_inventory', 'intune_backup'],
|
|
'legacy_aliases' => [],
|
|
'alias_retirement_path' => null,
|
|
'forbidden_platform_aliases' => ['governed_subject'],
|
|
],
|
|
],
|
|
'reason_namespaces' => [
|
|
'tenant_operability' => [
|
|
'owner_namespace' => 'tenant_operability',
|
|
'boundary_classification' => 'platform_core',
|
|
'owner_layer' => 'platform_core',
|
|
'compatibility_notes' => 'Tenant operability reasons are platform-core guardrails for workspace and tenant context.',
|
|
],
|
|
'execution_denial' => [
|
|
'owner_namespace' => 'execution_denial',
|
|
'boundary_classification' => 'platform_core',
|
|
'owner_layer' => 'platform_core',
|
|
'compatibility_notes' => 'Execution denial reasons remain platform-core run-legitimacy semantics.',
|
|
],
|
|
'operation_lifecycle' => [
|
|
'owner_namespace' => 'operation_lifecycle',
|
|
'boundary_classification' => 'platform_core',
|
|
'owner_layer' => 'platform_core',
|
|
'compatibility_notes' => 'Lifecycle reconciliation reasons remain platform-core monitoring semantics.',
|
|
],
|
|
'governance.baseline_compare' => [
|
|
'owner_namespace' => 'governance.baseline_compare',
|
|
'boundary_classification' => 'cross_domain_governance',
|
|
'owner_layer' => 'domain_owned',
|
|
'compatibility_notes' => 'Baseline-compare reason codes are governance-owned details translated through the platform boundary.',
|
|
],
|
|
'governance.artifact_truth' => [
|
|
'owner_namespace' => 'governance.artifact_truth',
|
|
'boundary_classification' => 'cross_domain_governance',
|
|
'owner_layer' => 'domain_owned',
|
|
'compatibility_notes' => 'Artifact-truth reason codes remain governance-owned and are surfaced through platform-safe summaries.',
|
|
],
|
|
'provider.microsoft_graph' => [
|
|
'owner_namespace' => 'provider.microsoft_graph',
|
|
'boundary_classification' => 'intune_specific',
|
|
'owner_layer' => 'provider_owned',
|
|
'compatibility_notes' => 'Microsoft Graph provider reasons remain provider-owned and Intune-specific.',
|
|
],
|
|
'provider.intune_rbac' => [
|
|
'owner_namespace' => 'provider.intune_rbac',
|
|
'boundary_classification' => 'intune_specific',
|
|
'owner_layer' => 'provider_owned',
|
|
'compatibility_notes' => 'Provider-owned Intune RBAC reasons remain Intune-specific.',
|
|
],
|
|
'rbac.intune' => [
|
|
'owner_namespace' => 'rbac.intune',
|
|
'boundary_classification' => 'intune_specific',
|
|
'owner_layer' => 'domain_owned',
|
|
'compatibility_notes' => 'RBAC detail remains Intune-specific domain context.',
|
|
],
|
|
'reason_translation.fallback' => [
|
|
'owner_namespace' => 'reason_translation.fallback',
|
|
'boundary_classification' => 'platform_core',
|
|
'owner_layer' => 'platform_core',
|
|
'compatibility_notes' => 'Fallback translation remains a platform-core compatibility seam until a domain owner is known.',
|
|
],
|
|
],
|
|
'registries' => [
|
|
'governance_subject_taxonomy_registry' => [
|
|
'registry_key' => 'governance_subject_taxonomy_registry',
|
|
'boundary_classification' => 'cross_domain_governance',
|
|
'owner_layer' => 'platform_core',
|
|
'source_class_or_file' => App\Support\Governance\GovernanceSubjectTaxonomyRegistry::class,
|
|
'canonical_nouns' => ['domain_key', 'subject_class', 'subject_type_key', 'subject_type_label'],
|
|
'allowed_consumers' => ['baseline_scope', 'compare', 'snapshot', 'review'],
|
|
'compatibility_notes' => 'Provides the governed-subject source of truth, resolves legacy policy-type payloads, and preserves inactive or future-domain entries without exposing them as active operator choices.',
|
|
],
|
|
'operation_catalog' => [
|
|
'registry_key' => 'operation_catalog',
|
|
'boundary_classification' => 'platform_core',
|
|
'owner_layer' => 'platform_core',
|
|
'source_class_or_file' => App\Support\OperationCatalog::class,
|
|
'canonical_nouns' => ['operation_type'],
|
|
'allowed_consumers' => ['monitoring', 'reporting', 'launch_surfaces', 'audit'],
|
|
'compatibility_notes' => 'Resolves canonical operation meaning from historical storage values without treating every stored raw string as equally canonical.',
|
|
],
|
|
'provider_reason_codes' => [
|
|
'registry_key' => 'provider_reason_codes',
|
|
'boundary_classification' => 'intune_specific',
|
|
'owner_layer' => 'provider_owned',
|
|
'source_class_or_file' => App\Support\Providers\ProviderReasonCodes::class,
|
|
'canonical_nouns' => ['reason_code'],
|
|
'allowed_consumers' => ['reason_translation'],
|
|
'compatibility_notes' => 'Provider-owned reason codes remain namespaced domain details and become platform-safe only through the reason-translation boundary.',
|
|
],
|
|
'inventory_policy_type_catalog' => [
|
|
'registry_key' => 'inventory_policy_type_catalog',
|
|
'boundary_classification' => 'intune_specific',
|
|
'owner_layer' => 'domain_owned',
|
|
'source_class_or_file' => App\Support\Inventory\InventoryPolicyTypeMeta::class,
|
|
'canonical_nouns' => ['policy_type'],
|
|
'allowed_consumers' => ['intune_adapter', 'inventory', 'backup'],
|
|
'compatibility_notes' => 'The supported Intune policy-type list is not a universal platform registry and must be wrapped before reuse on platform-near summaries.',
|
|
],
|
|
],
|
|
],
|
|
|
|
'hardening' => [
|
|
'intune_write_gate' => [
|
|
'enabled' => (bool) env('TENANTPILOT_INTUNE_WRITE_GATE_ENABLED', true),
|
|
'freshness_threshold_hours' => (int) env('TENANTPILOT_INTUNE_WRITE_GATE_FRESHNESS_HOURS', 24),
|
|
],
|
|
],
|
|
];
|