Verify Entra ID Tenant User Consent Setting via Graph API

Summary

During an infrastructure automation audit, an engineering team attempted to programmatically verify the User Consent Settings within Microsoft Entra ID (formerly Azure AD). The goal was to ensure that “User consent to apps accessing company data on their behalf” was strictly disabled to prevent shadow IT and unauthorized data exfiltration. Despite querying various Graph API endpoints and enterprise application permissions, the automation failed to retrieve the specific Global Tenant Setting required to validate this security posture.

Root Cause

The failure occurred due to a fundamental misunderstanding of the resource scope within the Microsoft Graph API. The engineers were searching for these settings within the context of Service Principals (Enterprise Applications) or Application Registrations, rather than the Tenant-level Configuration.

  • Scope Mismatch: The team was querying APIs related to application permissions (OAuth2 scopes), but the setting in question is a Directory-wide policy.
  • API Endpoint Misalignment: Most “Consent” APIs in Graph focus on what a specific app can do, whereas the requirement was to check if a user is permitted to grant those permissions in the first place.
  • Configuration vs. Permission: The target setting is a Tenant Property, not a permission object assigned to an identity or an application.

Why This Happens in Real Systems

In complex identity providers like Entra ID, there is a strict hierarchy between Global Policies and Object-level Permissions.

  • Abstraction Leaks: Documentation often uses the word “Consent” in multiple contexts (User Consent, Admin Consent, Scopes), leading engineers to look at the wrong layer of the stack.
  • Granular API Surface: Modern Cloud Identity Providers (IdPs) have thousands of endpoints. It is easy to find an endpoint for servicePrincipal/permissions while completely overlooking the directory/settings endpoint.
  • Configuration Drift: Security settings are often managed via UI (the Entra Portal), but once a system moves toward “Infrastructure as Code,” the lack of a direct API mapping for a specific UI toggle creates a visibility gap.

Real-World Impact

  • Security Non-Compliance: If automation fails to detect that user consent is enabled, an organization may unknowingly violate Zero Trust principles.
  • Data Exfiltration Risk: If a user can consent to an unvetted third-party application, they can grant that app User.Read or Mail.Read permissions, bypassing traditional perimeter security.
  • False Sense of Security: Passing a “Security Audit” based on flawed automation scripts leads to a massive blind spot in the Compliance Dashboard.

Example or Code

To programmatically verify this setting, you must query the servicePrincipal settings or specific directory configurations, typically via the get method on the tenant configuration endpoints.

# Correct approach: Querying the tenant-wide identity settings
# Note: This requires Directory.Read.All permissions

$tenantId = "your-tenant-id"
$url = "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" 
# Note: In actual implementation, specific tenant settings 
# are often accessed via the /directory/settings or specific 
# service principal configuration endpoints depending on the exact policy.

# Example using Microsoft Graph PowerShell SDK
Import-Module Microsoft.Graph.Identity.DirectoryManagement

# Fetching the specific settings related to user consent policy
$settings = Get-MgDirectorySetting | Where-Object { $_.DisplayName -eq "UserConsentSettings" }

if ($null -eq $settings) {
    Write-Host "Consent settings not explicitly defined (defaults to standard tenant policy)."
} else {
    $consentValue = $settings.Values | Where-Object { $_.Key -eq "allowUserConsent" }
    Write-Host "User Consent Enabled: $($consentValue.Value)"
}

How Senior Engineers Fix It

  • Identify the Policy Layer: Instead of searching for the setting on the “Application” object, senior engineers look for the Tenant Configuration or Directory Settings object.
  • Verify Permissions First: Before writing the script, they verify if the Service Principal running the automation has the Directory.Read.All or Policy.Read.All permissions required to see global settings.
  • Fallback to CLI/SDK: When REST APIs are ambiguous, they use official SDKs (like Microsoft Graph PowerShell) which often have pre-built types for complex directory objects.
  • Implement “Fail-Closed” Logic: If the automation cannot reach the API or the setting is missing, the script should report a Security Violation rather than assuming the setting is “Safe.”

Why Juniors Miss It

  • Searching by Keyword Only: Juniors often search for “Consent API” and pick the first result, which usually returns OAuth2 scopes rather than Tenant Policies.
  • Confusing Permissions with Policies: They treat a Security Policy (the rule) as a Permission (the right to do something).
  • UI-to-API Mapping Errors: They assume that because a setting is located under “Applications” in the Entra Portal, it must be part of the application or servicePrincipal API resource.

Leave a Comment