Skip to content

Entra ID App Registration

The server calls Graph with an app-only (client-credentials) token. Create an app registration with the following application permissions (all admin-consented):

Permission Used for
Directory.Read.All org info, users, groups, roles, OAuth grants, apps/SPs
User.Read.All users / guest users
Policy.Read.All conditional access, named locations, auth-methods & authorization policy, security defaults
AuditLog.Read.All sign-in logs, directory audits, MFA registration report
RoleManagement.Read.Directory role assignments
Application.Read.All app registrations, service principals
SecurityEvents.Read.All Secure Score + controls
SecurityAlert.Read.All security alerts
SecurityIncident.Read.All security incidents
IdentityRiskyUser.Read.All risky users (needs Entra ID P2)
IdentityRiskEvent.Read.All risk detections
DeviceManagementManagedDevices.Read.All Intune managed devices
DeviceManagementConfiguration.Read.All device compliance policies

Create it with the Azure CLI

No install needed — use the container image.

# 1. Run a throwaway azure-cli container and log in (device code)
docker run -d --name az-setup mcr.microsoft.com/azure-cli sleep 3600
docker exec -it az-setup az login --use-device-code --allow-no-subscriptions

# 2. Create the app + service principal
docker exec az-setup az ad app create \
  --display-name "365-MCP Security Auditor" --sign-in-audience AzureADMyOrg
docker exec az-setup az ad sp create --id <APP_ID>

# 3. Add the 13 Graph application permissions (resource 00000003-0000-0000-c000-000000000000),
#    then grant admin consent:
docker exec az-setup az ad app permission admin-consent --id <APP_ID>

# 4. Create a client secret (2-year)
docker exec az-setup az ad app credential reset --id <APP_ID> \
  --display-name "365-mcp" --years 2 --append

# 5. Clean up
docker rm -f az-setup

Tip: the permission GUIDs can be resolved from az ad sp show --id 00000003-0000-0000-c000-000000000000 --query "appRoles".

Record the Tenant ID, Client (App) ID, and Client Secret — they go in .env in the next step.