Skip to content

Microsoft Intune

Microsoft Intune is the MDM / device-management source. The integration talks to the Microsoft Graph API to pull managed devices, the tenant’s detected-app catalog, and the per-device installed apps, and writes them into MongoDB. It follows the shared integration lifecycle.

  • Router: app/api/v1/endpoints/intune.py, mounted at /api/v1/intune
  • Client: app/services/intune_client.py (IntuneClient)
  • Config collection: intune_config (keyed by tenant_id)

Authentication

Intune authenticates to Graph via MSAL client-credentials against an Azure app registration. Two auth methods are supported:

auth_methodRequired fields
certificatecert_thumbprint + cert_private_key (PEM text)
secretclient_secret

Both methods also need azure_tenant_id and azure_client_id. The client builds an msal.ConfidentialClientApplication and requests the https://graph.microsoft.com/.default scope. On save, the router validates that the fields for the chosen method are present (422 otherwise).

Required Graph application permissions (admin consent on the app registration):

  • DeviceManagementManagedDevices.Read.All
  • DeviceManagementApps.Read.All

Env seeding (_seed_intune_config) reads INTUNE_TENANT_ID, INTUNE_CLIENT_ID, INTUNE_CERT_THUMBPRINT and a PEM at INTUNE_CERT_KEY_PATH, and seeds the default tenant with certificate auth. (The same app registration and cert are reused by the Entra ID integration.) test-connection fetches one managed device to validate both credentials and consent.

What the sync pulls

The background _run_sync fetches everything in a thread-pool executor so auth stays responsive, then bulk-upserts:

DataSource callWritten to
Managed devicesget_managed_devices (/deviceManagement/managedDevices)intune_devices
Detected apps (deduped catalog)get_detected_appsdeduplicate_appsintune_apps
Per-device appsget_device_apps_batch (Graph $batch)inventory_items (source=intune)
  • Devices capture OS/version, compliance state, owner type, enrolled/last-sync timestamps, manufacturer/model/serial, and the owneruser_upn and user_display_name. Other integrations key off the device name and the owner UPN to reconcile machines and link users to assets.
  • Per-device apps are fetched with Graph JSON batching (get_device_apps_batch): up to 20 requests per $batch call, with per-response pagination re-batched in follow-up rounds and exponential-backoff retry on 429 throttling. The resulting device→app rows are upserted into the shared inventory_items collection tagged source="intune", carrying the device name, OS, and owner email/name so software reconciles and links to the right person.

Stale devices, apps and inventory rows are deleted, then rebuild_applications refreshes the Software rollup.

Routes

MethodPathPurpose
POST/api/v1/intune/configSave credentials (validates per-method fields)
GET/api/v1/intune/configGet config (secrets redacted)
DELETE/api/v1/intune/configRemove config + synced data
POST/api/v1/intune/test-connectionLive Graph credential + consent test
POST/api/v1/intune/syncStart a background sync
GET/api/v1/intune/sync-statusPoll sync status
GET/api/v1/intune/statsSummary counts + OS / compliance breakdowns
GET/api/v1/intune/devicesList managed devices (OS / compliance filters)
GET/api/v1/intune/appsList deduplicated detected apps by device count

See the overview for the lifecycle these routes share.