As enterprise IT departments scale their cloud infrastructure, manually clicking through the Azure Portal to manage user permissions becomes an unsustainable operational bottleneck. Managing Microsoft Entra ID (formerly Azure Active Directory) at scale requires absolute automation. While PowerShell modules (like Microsoft.Graph) provide a scripting interface, modern, cloud-native applications, serverless functions, and CI/CD pipelines require a programmatic, RESTful approach. By leveraging the Microsoft Graph API—specifically the Beta endpoints—administrators can autonomously assign, revoke, and audit highly privileged Entra ID administrative roles (such as Global Administrator or Exchange Administrator) directly via JSON payloads.
The Challenge of Role Assignments in Microsoft Graph
Interacting with Entra ID roles via the Graph API is notoriously complex. Unlike standard Azure resource roles (RBAC) which are assigned to specific scopes (like a subscription or resource group), Entra ID directory roles operate at the tenant level.
Furthermore, the v1.0 Graph API endpoint has historical limitations regarding directory role management, often requiring administrators to fall back to the legacy Azure AD Graph API (which is deprecated). To manage modern Entra ID roles (including custom roles and Privileged Identity Management [PIM] assignments) programmatically, you must utilize the beta endpoint of the Microsoft Graph API.
Registering the Application and Granting Permissions
Before you can make API calls, you must register a headless daemon application in Entra ID and grant it the precise API permissions required to modify directory roles. Because this application will run autonomously without a human user, it requires Application Permissions.
- Navigate to the Entra ID portal and select App registrations.
- Create a new registration named “Graph-Role-Automation”.
- Navigate to API permissions and add a permission for Microsoft Graph.
- Select Application permissions and search for
RoleManagement.ReadWrite.Directory. This is the highly sensitive permission required to assign tenant-wide admin roles. - Click Grant admin consent for [Tenant Name].
- Navigate to Certificates & secrets and generate a new Client Secret. Note this secret and the Application (Client) ID.
Authenticating and Acquiring the Bearer Token
Your script or application must first authenticate using the OAuth 2.0 Client Credentials flow to obtain an access token. Using a standard HTTP POST request (e.g., via curl, Python requests, or Node.js axios), request a token from the Microsoft identity platform.
POST https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id={client-id}
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret={client-secret}
&grant_type=client_credentials
The response will contain an access_token, which you must inject into the Authorization: Bearer header for all subsequent Graph API calls.
Discovering Role Definitions and Principal IDs
To assign a role, you cannot simply pass the string “Helpdesk Administrator”. You need the exact GUID of the Role Definition (the template) and the exact GUID of the User or Service Principal (the target) you wish to elevate.
To find the Role Definition ID for “Helpdesk Administrator”, query the beta role definitions endpoint:
GET https://graph.microsoft.com/beta/roleManagement/directory/roleDefinitions?$filter=displayName eq 'Helpdesk Administrator'
Extract the id from the JSON response (e.g., 729827e3-9c14-49f7-bb1b-9608f156bbb8).
Executing the Role Assignment
With the Role Definition ID and the target User ID acquired, you execute an HTTP POST request to the roleAssignments endpoint. This creates the linkage between the user and the administrative privilege.
POST https://graph.microsoft.com/beta/roleManagement/directory/roleAssignments
Content-type: application/json
{
"@odata.type": "#microsoft.graph.unifiedRoleAssignment",
"roleDefinitionId": "729827e3-9c14-49f7-bb1b-9608f156bbb8",
"principalId": "target-user-guid-here",
"directoryScopeId": "/"
}
The directoryScopeId of / indicates that the role is assigned at the root tenant level, which is standard for Entra ID directory roles.
If the HTTP request returns a 201 Created, the role assignment was successful. The target user immediately possesses the elevated privileges. By wrapping these API calls in automated Logic Apps or Terraform pipelines, organizations can implement rigorous Zero Trust architectures, programmatically granting and stripping administrative access precisely when required, entirely eliminating static, perpetual admin accounts.