RBAC and Custom Roles for AI Agents
Azure Role-Based Access Control (RBAC) is your first line of defense. By creating custom roles that explicitly exclude destructive actions, you ensure AI agents can only perform safe operations — no matter what commands they attempt to run.
Azure RBAC Fundamentals for Agent Access
Azure RBAC works by assigning roles to security principals (users, groups, service principals, managed identities) at a specific scope (management group, subscription, resource group, or resource). Each role is a collection of allowed and denied actions.
Built-in Roles: Reader vs Contributor vs Owner
| Role | Read | Create/Update | Delete | AI Agent Suitability |
|---|---|---|---|---|
| Reader | Yes | No | No | Safe but too limited for provisioning |
| Contributor | Yes | Yes | Yes | Too permissive — allows delete operations |
| Owner | Yes | Yes | Yes | Never use for AI agents — can also manage access |
Creating Custom Roles That Exclude Delete Actions
Custom roles let you grant exactly the permissions an AI agent needs while explicitly excluding destructive operations. Here is a JSON role definition for an "AI Agent Safe Deployer" role:
{
"Name": "AI Agent Safe Deployer",
"IsCustom": true,
"Description": "Allows AI agents to read and create Azure resources but denies all delete operations",
"Actions": [
"*/read",
"Microsoft.Compute/virtualMachines/write",
"Microsoft.Compute/virtualMachines/start/action",
"Microsoft.Compute/virtualMachines/restart/action",
"Microsoft.Network/virtualNetworks/write",
"Microsoft.Network/networkSecurityGroups/write",
"Microsoft.Network/publicIPAddresses/write",
"Microsoft.Network/networkInterfaces/write",
"Microsoft.Storage/storageAccounts/write",
"Microsoft.Storage/storageAccounts/listKeys/action",
"Microsoft.Web/sites/write",
"Microsoft.Web/sites/config/write",
"Microsoft.Sql/servers/write",
"Microsoft.Sql/servers/databases/write",
"Microsoft.ContainerService/managedClusters/write",
"Microsoft.Resources/subscriptions/resourceGroups/write"
],
"NotActions": [
"*/delete",
"Microsoft.Compute/virtualMachines/deallocate/action",
"Microsoft.Compute/virtualMachines/powerOff/action",
"Microsoft.Resources/subscriptions/resourceGroups/delete",
"Microsoft.Authorization/*/write",
"Microsoft.Authorization/*/delete",
"Microsoft.Authorization/roleAssignments/write",
"Microsoft.Authorization/roleDefinitions/write"
],
"DataActions": [],
"NotDataActions": [],
"AssignableScopes": [
"/subscriptions/YOUR-SUBSCRIPTION-ID"
]
}
# Create the custom role
az role definition create --role-definition @ai-agent-safe-deployer-role.json
# Create a Managed Identity for the AI agent
az identity create \
--name ai-agent-identity \
--resource-group rg-shared-infra
# Assign the custom role to the Managed Identity
az role assignment create \
--assignee $(az identity show --name ai-agent-identity \
--resource-group rg-shared-infra --query principalId -o tsv) \
--role "AI Agent Safe Deployer" \
--scope /subscriptions/YOUR-SUBSCRIPTION-ID
Deny Assignments for Destructive Operations
Azure deny assignments explicitly block specific actions, even if a role grants them. While deny assignments are primarily managed through Azure Blueprints, you can also create them via the REST API:
{
"properties": {
"denyAssignmentName": "Deny Agent Delete Operations",
"description": "Prevents AI agent identities from performing delete operations",
"permissions": [
{
"actions": [
"*/delete",
"Microsoft.Resources/subscriptions/resourceGroups/delete"
],
"notActions": [],
"dataActions": [],
"notDataActions": []
}
],
"scope": "/subscriptions/YOUR-SUBSCRIPTION-ID",
"doNotApplyToChildScopes": false,
"principals": [
{
"id": "AI-AGENT-MANAGED-IDENTITY-PRINCIPAL-ID",
"type": "ServicePrincipal"
}
],
"excludePrincipals": []
}
}
Managed Identities for AI Agent Workloads
Managed Identities eliminate the need for storing credentials in environment variables or configuration files. There are two types:
| Type | Lifecycle | Best For |
|---|---|---|
| System-assigned | Tied to the Azure resource (VM, App Service, etc.) | Agent running on a single Azure resource |
| User-assigned | Independent resource, can be shared across resources | Agent identity used across multiple compute resources |
# Enable system-assigned managed identity on a VM az vm identity assign \ --resource-group rg-ai-agents \ --name vm-ai-agent-runner # Or create a user-assigned identity for sharing across VMs az identity create \ --name uai-ai-agent \ --resource-group rg-shared-infra # Assign the safe deployer role to the managed identity PRINCIPAL_ID=$(az identity show \ --name uai-ai-agent \ --resource-group rg-shared-infra \ --query principalId -o tsv) az role assignment create \ --assignee $PRINCIPAL_ID \ --role "AI Agent Safe Deployer" \ --scope /subscriptions/YOUR-SUBSCRIPTION-ID
Conditional Access Policies
Azure AD Conditional Access can add additional guardrails based on context — location, device compliance, risk level, and more:
-
Restrict Agent Access by Network Location
Configure Conditional Access to only allow the AI agent's service principal to authenticate from specific IP ranges (e.g., your CI/CD pipeline's static IPs or your VNet's NAT gateway).
-
Require Compliant Devices
If agents run on developer workstations, require that the device is Intune-compliant. This prevents agents from operating on compromised or unmanaged machines.
-
Sign-in Risk Assessment
Azure AD Identity Protection can detect unusual sign-in patterns. If an agent's service principal suddenly authenticates from an unexpected location, Conditional Access can block the session.
PIM (Privileged Identity Management) for Just-in-Time Access
Azure AD PIM allows you to grant time-limited, approval-required role activations. This is ideal for cases where an AI agent occasionally needs elevated permissions:
# Step 1: AI agent has "Reader" role by default (safe baseline)
# Step 2: When delete permission is needed, a human activates PIM
# Using Azure CLI to check eligible role assignments
az rest --method GET \
--url "https://management.azure.com/subscriptions/SUB-ID/providers/Microsoft.Authorization/roleEligibilityScheduleInstances?api-version=2020-10-01"
# PIM activation via REST API (would be triggered by human approval)
az rest --method PUT \
--url "https://management.azure.com/subscriptions/SUB-ID/providers/Microsoft.Authorization/roleAssignmentScheduleRequests/REQUEST-ID?api-version=2020-10-01" \
--body '{
"properties": {
"principalId": "AGENT-PRINCIPAL-ID",
"roleDefinitionId": "/subscriptions/SUB-ID/providers/Microsoft.Authorization/roleDefinitions/CONTRIBUTOR-ROLE-ID",
"requestType": "SelfActivate",
"scheduleInfo": {
"startDateTime": "2026-03-20T10:00:00Z",
"expiration": {
"type": "AfterDuration",
"duration": "PT1H"
}
},
"justification": "Approved cleanup of deprecated dev resources"
}
}'
# After 1 hour, the elevated role automatically deactivates
# Agent returns to Reader-only access
Lilly Tech Systems