Forum Discussion
How to Fix Azure Event Grid Entra Authentication issue for ACS and Dynamics 365 integrated Webhooks
Introduction:
Azure Event Grid is a powerful event routing service that enables event-driven architectures in Azure. When delivering events to webhook endpoints, security becomes paramount. Microsoft provides a secure webhook delivery mechanism using Microsoft Entra ID (formerly Azure Active Directory) authentication through the AzureEventGridSecureWebhookSubscriber role.
Problem Statement:
When integrating Azure Communication Services with Dynamics 365 Contact Center using Microsoft Entra ID-authenticated Event Grid webhooks, the Event Grid subscription deployment fails with an error: "HTTP POST request failed with unknown error code" with empty HTTP status and code.
For example:
Important Note:
Before moving forward, please verify that you have the Owner role assigned on app to create event subscription. Refer to the Microsoft guidelines below to validate the required prerequisites before proceeding:
Set up incoming calls, call recording, and SMS services | Microsoft Learn
Why This Happens:
This happens because AzureEventGridSecureWebhookSubscriber role is NOT properly configured on Microsoft EventGrid SP (Service Principal) and event subscription entra ID or application who is trying to create event grid subscription.
What is AzureEventGridSecureWebhookSubscriber Role:
The AzureEventGridSecureWebhookSubscriber is an Azure Entra application role that:
- Enables your application to verify the identity of event senders
- Allows specific users/applications to create event subscriptions
- Authorizes Event Grid to deliver events to your webhook
How It Works:
- Role Creation: You create this app role in your destination webhook application's Azure Entra registration
- Role Assignment: You assign this role to:
- Microsoft Event Grid service principal (so it can deliver events)
- Either Entra ID / Entra User or Event subscription creator applications (so they can create event grid subscriptions)
- Token Validation: When Event Grid delivers events, it includes an Azure Entra token with this role claim
- Authorization Check: Your webhook validates the token and checks for the role
Key Participants:
- Webhook Application (Your App)
- Purpose: Receives and processes events
- App Registration: Created in Azure Entra
- Contains: The AzureEventGridSecureWebhookSubscriber app role
- Validates: Incoming tokens from Event Grid
- Microsoft Event Grid Service Principal
- Purpose: Delivers events to webhooks
- App ID: Different per Azure cloud (Public, Government, etc.)
- Public Azure: 4962773b-9cdb-44cf-a8bf-237846a00ab7
- Needs: AzureEventGridSecureWebhookSubscriber role assigned
- Event Subscription Creator Entra or Application
- Purpose: Creates event subscriptions
- Could be: You, Your deployment pipeline, admin tool, or another application
- Needs: AzureEventGridSecureWebhookSubscriber role assigned
Although the full PowerShell script is documented in the below Event Grid documentation, it may be complex to interpret and troubleshoot.
To improve accessibility, the following section provides a simplified step-by-step tested solution along with verification steps suitable for all users including non-technical:
Steps:
STEP 1: Verify/Create Microsoft.EventGrid Service Principal
Azure Portal → Microsoft Entra ID → Enterprise applications
Change filter to Application type: Microsoft Applications
Search for: Microsoft.EventGrid
Ideally, your Azure subscription should include this application ID, which is common across all Azure subscriptions: 4962773b-9cdb-44cf-a8bf-237846a00ab7.
If this application ID is not present, please contact your Azure Cloud Administrator.
STEP 2: Create the App Role "AzureEventGridSecureWebhookSubscriber"
Using Azure Portal:
- Navigate to your Webhook App Registration:
- Azure Portal → Microsoft Entra ID → App registrations
- Click All applications
- Find your app by searching OR use the Object ID you have
- Click on your app
- Create the App Role:
- Display name: AzureEventGridSecureWebhookSubscriber
- Allowed member types: Both (Users/Groups + Applications)
- Value: AzureEventGridSecureWebhookSubscriber
- Description: Azure Event Grid Role
- Do you want to enable this app role?: Yes
- In left menu, click App roles
- Click + Create app role
- Fill in the form:
- Click Apply
STEP 3: Assign YOUR USER to the Role
Using Azure Portal:
- Switch to Enterprise Application view:
- Azure Portal → Microsoft Entra ID → Enterprise applications
- Search for your webhook app (by name)
- Click on it
- Assign yourself:
- In left menu, click Users and groups
- Click + Add user/group
- Under Users, click None Selected
- Search for your user account (use your email)
- Select yourself
- Click Select
- Under Select a role, click None Selected
- Select AzureEventGridSecureWebhookSubscriber
- Click Select
- Click Assign
STEP 4: Assign Microsoft.EventGrid Service Principal to the Role
This step MUST be done via PowerShell or Azure CLI (Portal doesn't support this directly as we have seen) so PowerShell is recommended
You will need to execute this step with the help of your Entra admin.
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "AppRoleAssignment.ReadWrite.All"
# Replace this with your webhook app's Application (client) ID
$webhookAppId = "YOUR-WEBHOOK-APP-ID-HERE" #starting with c5
# Get your webhook app's service principal
$webhookSP = Get-MgServicePrincipal -Filter "appId eq '$webhookAppId'"
Write-Host " Found webhook app: $($webhookSP.DisplayName)"
# Get Event Grid service principal
$eventGridSP = Get-MgServicePrincipal -Filter "appId eq '4962773b-9cdb-44cf-a8bf-237846a00ab7'"
Write-Host " Found Event Grid service principal"
# Get the app role
$appRole = $webhookSP.AppRoles | Where-Object {$_.Value -eq "AzureEventGridSecureWebhookSubscriber"}
Write-Host " Found app role: $($appRole.DisplayName)"
# Create the assignment
New-MgServicePrincipalAppRoleAssignment `
-ServicePrincipalId $eventGridSP.Id `
-PrincipalId $eventGridSP.Id `
-ResourceId $webhookSP.Id `
-AppRoleId $appRole.Id
Write-Host "Successfully assigned Event Grid to your webhook app!"
Verification Steps:
- Verify the App Role was created:
- Your App Registration → App roles
- You should see: AzureEventGridSecureWebhookSubscriber
- Verify your user assignment:
- Enterprise application (your webhook app) → Users and groups
- You should see your user with role AzureEventGridSecureWebhookSubscriber
- Verify Event Grid assignment:
- Same location → Users and groups
- You should see Microsoft.EventGrid with role AzureEventGridSecureWebhookSubscriber
Sample Flow:
Analogy For Simplification:
Lets think it similar to the construction site bulding where you are the owner of the building.
Building = Azure Entra app (webhook app)
Building (Azure Entra App Registration for Webhook)
├─ Building Name: "MyWebhook-App"
├─ Building Address: Application ID
├─ Building Owner: You
├─ Security System: App Roles (the security badges you create)
└─ Security Team: Azure Entra and your actual webhook auth code (which validates tokens) like doorman
Step 1: Creat the badge (App role)
You (the building owner) create a special badge:
- Badge name: "AzureEventGridSecureWebhookSubscriber"
- Badge color: Let's say it's GOLD
- Who can have it: Companies (Applications) and People (Users)
This badge is stored in your building's system (Webhook App Registration)
Step 2: Give badge to the Event Grid Service:
Event Grid: "Hey, I need to deliver messages to your building"
You: "Okay, here's a GOLD badge for your SP"
Event Grid: *wears the badge*
Now Event Grid can:
- Show the badge to Azure Entra
- Get tokens that say "I have the GOLD badge"
- Deliver messages to your webhook
Step 3: Give badge to yourself (or your deployment tool)
You also need a GOLD badge because:
- You want to create event grid event subscriptions
- Entra checks: "Does this person have a GOLD badge?"
- If yes: You can create subscriptions
- If no: "Access denied"
Your deployment pipeline also gets a GOLD badge:
- So it can automatically set up event subscriptions during CI/CD deployments
Disclaimer:
The sample scripts provided in this article are provided AS IS without warranty of any kind. The author is not responsible for any issues, damages, or problems that may arise from using these scripts. Users should thoroughly test any implementation in their environment before deploying to production. Azure services and APIs may change over time, which could affect the functionality of the provided scripts. Always refer to the latest Azure documentation for the most up-to-date information.
Thanks for reading this blog! I hope you found it helpful and informative for this specific integration use case 😀