Files
AutopilotMonitor/src/Shared/AutopilotMonitor.Shared/Models/Graph/GraphAppPermissions.cs
T
Oliver Kieselbach 2e736f40ad feat(backend,shared): Intune Enrollment Validation admits enrolled devices without pre-registration (D-282)
The certificate's Intune managedDevice id is looked up in the tenant's Intune. With the tenant
switch ValidateIntuneDeviceBinding on, that lookup is the last accepting link of the validator
chain: an enrolled device that is not being retired, wiped or deleted is admitted as
ValidatorType.IntuneEnrollment. A 404 for a certificate younger than 60 minutes is
NotFoundRecentEnrollment (503, never cached); a missing grant is 503 with 120 s.

For devices another validator admitted, the lookup only observes: in the background, never
admitting or rejecting, and only when the app token carries
DeviceManagementManagedDevices.Read.All, so a tenant without the add-on costs no Graph call.
Outcomes ride on the request row (CertDeviceBinding, role, serial match, owner and enrollment
type).

TenantConfiguration.HasAnyDeviceValidation() is the single gate precondition; the feature flags
expose it as deviceValidationEnabled (replaces validateAutopilotDevice).

The agent parses ValidatorType strictly: release the agent before this backend.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 11:57:26 +02:00

53 lines
3.0 KiB
C#

namespace AutopilotMonitor.Shared.Models.Graph
{
/// <summary>
/// Constant catalog of Microsoft Graph application permission names referenced by the
/// Autopilot Monitor backend. Centralised so feature toggles, the customer-side grant
/// script, and the runtime permission detector cannot drift apart.
/// </summary>
public static class GraphAppPermissions
{
/// <summary>
/// Core enrollment device-validation permission. Required to read
/// <c>windowsAutopilotDeviceIdentities</c> (Autopilot Device Validation) and
/// <c>importedDeviceIdentities</c> (Corporate Identifier Validation). Part of the
/// publisher manifest's default-consent set — present in the SP's token <c>roles</c>
/// claim once admin consent has been granted by anyone in the tenant. Used by the
/// access-check probe to silently reconcile pre-approved consent.
/// </summary>
public const string DeviceManagementServiceConfigReadAll = "DeviceManagementServiceConfig.Read.All";
/// <summary>Read display names + file names of Intune device management scripts (Platform Scripts + Remediations).</summary>
public const string DeviceManagementScriptsReadAll = "DeviceManagementScripts.Read.All";
/// <summary>Read Intune configuration profiles (future use — policy display names).</summary>
public const string DeviceManagementConfigurationReadAll = "DeviceManagementConfiguration.Read.All";
/// <summary>Read Intune managed apps (future use — Win32 app display names not yet covered).</summary>
public const string DeviceManagementAppsReadAll = "DeviceManagementApps.Read.All";
/// <summary>
/// Read Intune managed device objects (<c>deviceManagement/managedDevices</c>). Optional
/// add-on permission backing Intune Enrollment Validation, which resolves the managedDevice
/// id carried in the agent's client certificate in the tenant it claims. Not part of the
/// default-consent set — must be granted per tenant.
/// </summary>
public const string DeviceManagementManagedDevicesReadAll = "DeviceManagementManagedDevices.Read.All";
/// <summary>
/// Read Windows 365 Cloud PC objects (<c>virtualEndpoint/cloudPCs</c>). Optional add-on
/// permission backing the W365 Cloud PC device validator — Cloud PCs are never
/// Autopilot-registered, so validation resolves them through the service-side Cloud PC
/// inventory instead.
/// </summary>
public const string CloudPCReadAll = "CloudPC.Read.All";
/// <summary>
/// Application roles the published app manifest requests — the set a tenant-wide admin
/// consent grants by itself. Everything else a service principal holds is a tenant-side
/// add-on grant (<see cref="GraphFeatureCatalog"/>) that no re-consent can produce.
/// </summary>
public static readonly string[] DefaultConsentSet = { DeviceManagementServiceConfigReadAll };
}
}