Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
If you want Azure Policy to behave differently based on who (or what) makes a
request, use the requestContext().identity function.
This function lets you inspect caller identity information at policy evaluation time, so you can write policies such as:
- allow only user-initiated changes for sensitive resource types
- block updates from unapproved client applications
- require stronger sign-in context (for example, MFA indicators) before specific operations
Why this function matters
Most policy rules evaluate the target resource payload. That approach works well for enforcing configuration, but it doesn't provide any information about the caller.
requestContext().identity fills that gap by exposing request identity metadata in policy rule expressions.
At a high level, you can evaluate:
idtyp: caller identity type (app,user, ornull)appid: client application ID used for the requestacrs: authentication context class references (used to inspect sign-in context, such as MFA-related values)http://schemas.microsoft.com/identity/claims/objectidentifier: caller object ID (user or service principal object identifier)
Important
When you use requestContext().identity, Azure Policy enforcement still occurs at
request time (for example, deny, modify, and deployIfNotExists). However, compliance scans
for that policy are marked as NotApplicable. This pattern is best when your goal is real-time
enforcement on incoming create/update operations, not post-deployment compliance reporting.
Pattern: safely read identity fields with tryGet
Identity claims might be missing for some requests. Use tryGet() so your expression doesn't fail
when a key is missing.
Example:
{
"value": "[tryGet(requestContext().identity, 'idtyp')]",
"equals": "user"
}
Example 1: allow only approved client apps
This example restricts writes to requests coming from a known allowlist of client app IDs.
{
"mode": "All",
"parameters": {
"allowedClientAppIds": {
"type": "Array",
"metadata": {
"displayName": "Allowed client application IDs",
"description": "List of Entra app IDs permitted to perform write operations."
}
}
},
"policyRule": {
"if": {
"allOf": [
{
"value": "[tryGet(requestContext().identity, 'appid')]",
"notIn": "[parameters('allowedClientAppIds')]"
}
]
},
"then": {
"effect": "deny"
}
}
}
This restriction is useful for guarding automation boundaries so only approved deployment tooling can modify selected resource providers.
Example 2: inspect MFA-related auth context
The acrs claim can include multiple comma-separated values. Use split() to evaluate them.
{
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Authorization/roleAssignments"
},
{
"value": "p1",
"notIn": "[split(tryGet(requestContext().identity, 'acrs'), ',')]"
}
]
},
"then": {
"effect": "deny"
}
}
The exact acrs values depend on your identity and conditional access design, so validate the
expected values in your tenant before broad rollout.
Example 3: scope by specific caller object IDs
You can inspect object identifier claims for precise allow or deny logic:
{
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Resources/subscriptions/resourceGroups"
},
{
"value": "[tryGet(requestContext().identity, 'http://schemas.microsoft.com/identity/claims/objectidentifier')]",
"notIn": "[parameters('approvedObjectIds')]"
}
]
},
"then": {
"effect": "deny"
}
}
This pattern is strict and explicit, but it requires good operational hygiene to keep identity lists current.
Design tips before production rollout
- Start with
auditor assign with enforcement disabled to validate behavior before enforcingdeny. - Pilot at a narrow scope (single resource group or isolated subscription) before broad assignment. To learn more about staged rollout best practices, see Safe deployment of Azure Policy assignments.
- Communicate clearly with platform and security teams that compliance state is
NotApplicablefor these policies. - Pair identity-based rules with resource-configuration policies for layered governance.
Wrap-up
requestContext().identity gives Azure Policy request-time awareness of caller identity so you can
govern who can perform changes, not just what the resource should look like.
Used carefully, it's a strong control for high-impact operations, especially when combined with standard configuration policies and staged rollout practices.