Adding App Identity to Directory Readers Role in Azure
When configuring an Azure SQL Managed Instance or Azure SQL Database to authenticate applications using a User-Assigned Managed Identity (UMI), creating external database users (CREATE USER [...] FROM EXTERNAL PROVIDER) requires the SQL Server’s own identity to query Microsoft Entra ID (formerly Azure Active Directory).
If the SQL Server identity lacks directory read permissions in Entra ID, executing CREATE USER fails with Msg 37353:
Msg 37353, Level 16, State 1, Line 1
Server identity does not have Azure Active Directory Readers permission. Please follow the steps here : https://docs.microsoft.com/en-us/azure/azure-sql/database/authentication-aad-service-principal
Why This Error Happens
When you execute CREATE USER [app-identity] FROM EXTERNAL PROVIDER, Azure SQL must resolve the display name into an Object ID (oid) and Application ID (appId) inside your Microsoft Entra tenant. By default, a newly created User-Assigned Managed Identity or System-Assigned Managed Identity cannot read other directory objects unless it is either:
- Assigned to the Directory Readers role in Microsoft Entra ID, or
- Granted fine-grained Microsoft Graph application permissions (
User.Read.All,GroupMember.Read.All, andApplication.Read.All).
Recommended Solution: Microsoft Graph PowerShell SDK
Because Microsoft retired the legacy AzureAD PowerShell module, use the Microsoft Graph PowerShell SDK (Microsoft.Graph) with a Global Administrator or Privileged Role Administrator account to assign the Managed Identity to the Directory Readers role:
# Connect with role management and directory read scopes
Connect-MgGraph -Scopes "RoleManagement.ReadWrite.Directory", "Directory.Read.All"
# Look up the Service Principal of your User-Assigned Managed Identity
$umi = Get-MgServicePrincipal -Filter "displayName eq 'UserAssignedIdentityName'"
# Retrieve (or activate) the Directory Readers role template (TemplateId: 88d8e3e3-8f55-4a1e-953a-9b9898b8876b)
$role = Get-MgDirectoryRole -Filter "displayName eq 'Directory Readers'"
if (-not $role) {
$roleTemplate = Get-MgDirectoryRoleTemplate | Where-Object { $_.DisplayName -eq "Directory Readers" }
$role = New-MgDirectoryRole -DirectoryRoleTemplateId $roleTemplate.Id
}
# Assign the Managed Identity to the Directory Readers role
$body = @{
"@odata.id" = "https://graph.microsoft.com/v1.0/directoryObjects/$($umi.Id)"
}
New-MgDirectoryRoleMemberByRef -DirectoryRoleId $role.Id -BodyParameter $body
Legacy PowerShell Method (AzureAD Module)
If you are maintaining an older automation runbook that still uses the legacy AzureAD module, the equivalent commands are:
Connect-AzureAD
$umi = Get-AzureADServicePrincipal -SearchString "UserAssignedIdentityName"
$role = Get-AzureADDirectoryRole | Where-Object {$_.DisplayName -eq "Directory Readers"}
Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $umi.ObjectId
Verification
After assigning the role, verify the membership in Microsoft Entra ID → Roles and administrators → Directory Readers. Once propagated (usually within 1–2 minutes), rerun your T-SQL statement on the Azure SQL instance:
CREATE USER [my-app-managed-identity] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [my-app-managed-identity];
ALTER ROLE db_datawriter ADD MEMBER [my-app-managed-identity];