pythonazuremicrosoft-graph-apimicrosoft-entra-id

Changing Azure PIM Group approvals and notification settings via MS Graph API


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?


Solution

  • 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:

    enter image description here

    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:

    enter image description here

    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:

    enter image description here

    To confirm that, I checked the same in the Portal where the Approver was changed successfully as below:

    enter image description here

    Similarly, I have the below notification settings configured for the PIMgroup01 group with no additional recipient:

    enter image description here

    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:

    enter image description here

    When I checked the same in the Portal, the additional recipient added successfully like this:

    enter image description here

    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:

    enter image description here

    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:

    Update unifiedRoleManagementPolicyRule - Microsoft Graph