I'm writing a some code to allow my team to work with PIM for Groups without needing to access the Azure Portal. I want to set PIM approvals and notification settings for a group, however, I can't find any graph API information for changing these settings.
Is there any Graph API endpoint for Python?
To set Azure PIM Group approvals and notification settings using the Microsoft Graph API, you need to update the rules defined for a role management policy.
Initially, run the below API call to retrieve the policies that are scoped to the group and apply to PIM for groups membership and ownership.
GET https://graph.microsoft.com/v1.0/policies/roleManagementPolicies?$filter=scopeId eq 'groupId' and scopeType eq 'Group'&$expand=rules($select=id)
Response:
Now, you need to update the rules to change PIM Group approvals and notification settings.
I have one PIM group role setting with the below user as Approver:
To change this PIM group role setting with a different user as Approver, I used the below Microsoft Graph API call:
PATCH https://graph.microsoft.com/v1.0/policies/roleManagementPolicies/policyId/rules/Approval_EndUser_Assignment
{
"@odata.type": "#microsoft.graph.unifiedRoleManagementPolicyApprovalRule",
"id": "Approval_EndUser_Assignment",
"target": {
"@odata.type": "microsoft.graph.unifiedRoleManagementPolicyRuleTarget",
"caller": "EndUser",
"operations": [
"All"
],
"level": "Assignment",
"inheritableSettings": [],
"enforcedSettings": []
},
"setting": {
"@odata.type": "microsoft.graph.approvalSettings",
"isApprovalRequired": true,
"isApprovalRequiredForExtension": false,
"isRequestorJustificationRequired": true,
"approvalMode": "SingleStage",
"approvalStages": [
{
"@odata.type": "microsoft.graph.unifiedApprovalStage",
"approvalStageTimeOutInDays": 1,
"isApproverJustificationRequired": true,
"escalationTimeInMinutes": 0,
"primaryApprovers": [
{
"@odata.type": "#microsoft.graph.singleUser",
"userId": "bd892748-axx4-4188-a892-e1xxxxxx"
}
],
"isEscalationEnabled": false,
"escalationApprovers": []
}
]
}
}
Response:
To confirm that, I checked the same in the Portal where the Approver was changed successfully as below:
Similarly, I have the below notification settings configured for the PIMgroup01 group with no additional recipient:
To change PIM group notification settings by adding an additional recipient, I used the below API call:
PATCH https://graph.microsoft.com/v1.0/policies/roleManagementPolicies/policyId/rules/Notification_Admin_Admin_Eligibility
{
"@odata.type": "#microsoft.graph.unifiedRoleManagementPolicyNotificationRule",
"id": "Notification_Admin_Admin_Eligibility",
"target": {
"@odata.type": "microsoft.graph.unifiedRoleManagementPolicyRuleTarget"
},
"notificationType": "Email",
"recipientType": "Admin",
"notificationLevel": "All",
"isDefaultRecipientsEnabled": "true",
"notificationRecipients": [
"sri@xxxxxxx.onmicrosoft.com"
]
}
Response:
When I checked the same in the Portal, the additional recipient added successfully like this:
To know which rule to update for what role setting, you can check this Microsoft Document.
If you are generating an access token using a client credentials flow in Python, make sure to grant the RoleManagementPolicy.ReadWrite.AzureADGroup permission of the Application type with consent:
Sample Python code:
import requests
import msal
CLIENT_ID = "appId"
CLIENT_SECRET = "secret"
TENANT_ID = "tenantId"
AUTHORITY = f"https://login.microsoftonline.com/{TENANT_ID}"
SCOPE = ["https://graph.microsoft.com/.default"]
app = msal.ConfidentialClientApplication(CLIENT_ID, authority=AUTHORITY, client_credential=CLIENT_SECRET)
token_result = app.acquire_token_for_client(scopes=SCOPE)
if "access_token" in token_result:
access_token = token_result["access_token"]
else:
raise Exception("Failed to retrieve access token.")
HEADERS = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
GROUP_ID = "groupId"
policy_url = f"https://graph.microsoft.com/v1.0/policies/roleManagementPolicies?$filter=scopeId eq '{GROUP_ID}' and scopeType eq 'Group'&$expand=rules($select=id)"
response = requests.get(policy_url, headers=HEADERS)
if response.status_code in [200, 204]:
policies = response.json().get("value", [])
if policies:
policy_id = policies[0]["id"]
else:
raise Exception("No PIM policy found for the group.")
else:
raise Exception(f"Failed to retrieve policies: {response.status_code} {response.text}")
approval_rule_url = f"https://graph.microsoft.com/v1.0/policies/roleManagementPolicies/{policy_id}/rules/Approval_EndUser_Assignment"
approval_payload = {
"@odata.type": "#microsoft.graph.unifiedRoleManagementPolicyApprovalRule",
"id": "Approval_EndUser_Assignment",
"target": {
"@odata.type": "microsoft.graph.unifiedRoleManagementPolicyRuleTarget",
"caller": "EndUser",
"operations": ["All"],
"level": "Assignment",
"inheritableSettings": [],
"enforcedSettings": []
},
"setting": {
"@odata.type": "microsoft.graph.approvalSettings",
"isApprovalRequired": True,
"isApprovalRequiredForExtension": False,
"isRequestorJustificationRequired": True,
"approvalMode": "SingleStage",
"approvalStages": [
{
"@odata.type": "microsoft.graph.unifiedApprovalStage",
"approvalStageTimeOutInDays": 1,
"isApproverJustificationRequired": True,
"escalationTimeInMinutes": 0,
"primaryApprovers": [
{
"@odata.type": "#microsoft.graph.singleUser",
"userId": "bd892748-axx4-4188-a892-e1xxxxxx"
}
],
"isEscalationEnabled": False,
"escalationApprovers": []
}
]
}
}
response = requests.patch(approval_rule_url, headers=HEADERS, json=approval_payload)
if response.status_code in [200, 204]:
print("PIM approval settings updated successfully.")
else:
print(f"Failed to update PIM approval settings: {response.status_code} {response.text}")
notification_rule_url = f"https://graph.microsoft.com/v1.0/policies/roleManagementPolicies/{policy_id}/rules/Notification_Admin_Admin_Eligibility"
notification_payload = {
"@odata.type": "#microsoft.graph.unifiedRoleManagementPolicyNotificationRule",
"id": "Notification_Admin_Admin_Eligibility",
"target": {
"@odata.type": "microsoft.graph.unifiedRoleManagementPolicyRuleTarget"
},
"notificationType": "Email",
"recipientType": "Admin",
"notificationLevel": "All",
"isDefaultRecipientsEnabled": "true",
"notificationRecipients": [
"sri@xxxxxxx.onmicrosoft.com"
]
}
response = requests.patch(notification_rule_url, headers=HEADERS, json=notification_payload)
if response.status_code in [200, 204]:
print("PIM notification settings updated successfully.")
else:
print(f"Failed to update PIM notification settings: {response.status_code} {response.text}")
Reference: