Provision Microsoft Entra Agent Identity Blueprints, BlueprintPrincipals, and per-instance Agent Identities via Microsoft Graph, and configure OAuth 2.0 token exchange (fmi_path, OBO, cross-tenant) including the Microsoft Entra SDK for AgentID sidecar. USE FOR: Agent Identity Blueprint, BlueprintPrincipal, agent OAuth, fmi_path token exchange, agent OBO, Workload Identity Federation for agents, polyglot agent auth, Microsoft.Identity.Web.AgentIdentities. DO NOT USE FOR: standard Entra app registration (use entra-app-registration), Microsoft Foundry agent authoring (use microsoft-foundry).
$npx -y skills add microsoft/azure-skills --skill entra-agent-idInstalls into the current project.
Run `npx skills use "https://github.com/microsoft/azure-skills" --skill "microsoft/azure-skills/entra-agent-id"` and follow the generated skill instructions now. Read its complete output, redirecting it to a temporary file first if necessary. Resolve relative paths from the supporting-files directory it provides.
Use the skills in "https://github.com/microsoft/azure-skills" that are relevant to the current task. Run `npx skills add "https://github.com/microsoft/azure-skills"` and select the relevant skills, then follow their instructions.
| 1 | # Microsoft Entra Agent ID |
| 2 | |
| 3 | Create and manage OAuth 2.0-capable identities for AI agents using Microsoft Graph. Every agent instance gets a distinct identity, audit trail, and independently-scoped permission grants. |
| 4 | |
| 5 | ## Quick Reference |
| 6 | |
| 7 | | Property | Value | |
| 8 | |----------|-------| |
| 9 | | Service | Microsoft Entra Agent ID | |
| 10 | | API | Microsoft Graph (`https://graph.microsoft.com/v1.0`) | |
| 11 | | Required role | Agent Identity Developer, Agent Identity Administrator, or Application Administrator | |
| 12 | | Object model | Blueprint (application) → BlueprintPrincipal (SP) → Agent Identity (SP) | |
| 13 | | Runtime exchange | Two-step `fmi_path` exchange (autonomous and OBO) | |
| 14 | | .NET helper | `Microsoft.Identity.Web.AgentIdentities` | |
| 15 | | Polyglot helper | Microsoft Entra SDK for AgentID (sidecar container) | |
| 16 | |
| 17 | ## When to Use This Skill |
| 18 | |
| 19 | - Provisioning a new Agent Identity Blueprint and BlueprintPrincipal |
| 20 | - Creating per-instance Agent Identities under a Blueprint |
| 21 | - Configuring credentials (FIC, Managed Identity, or client secret) on the Blueprint |
| 22 | - Implementing the two-step `fmi_path` runtime token exchange (autonomous or OBO) |
| 23 | - Cross-tenant agent token flows |
| 24 | - Deploying the Microsoft Entra SDK for AgentID sidecar for polyglot agents (Python, Node, Go, Java) |
| 25 | - Granting per-Agent-Identity application (`appRoleAssignments`) or delegated (`oauth2PermissionGrants`) permissions |
| 26 | - Diagnosing Agent ID errors such as `AADSTS82001`, `AADSTS700211`, or `PropertyNotCompatibleWithAgentIdentity` |
| 27 | |
| 28 | ## MCP Tools |
| 29 | |
| 30 | | Tool | Use | |
| 31 | |------|-----| |
| 32 | | `mcp_azure_mcp_documentation` | Search Microsoft Learn for current Agent ID setup, Graph API shapes, and SDK configuration | |
| 33 | |
| 34 | There is no dedicated Agent Identity MCP server today. This skill guides direct Microsoft Graph API calls (PowerShell or Python `requests`). Use `mcp_azure_mcp_documentation` to verify request bodies and endpoints against current docs before running. |
| 35 | |
| 36 | ## Before You Start |
| 37 | |
| 38 | Use the `mcp_azure_mcp_documentation` tool to search Microsoft Learn for current Agent ID documentation: |
| 39 | - "Microsoft Entra Agent ID setup instructions" |
| 40 | - "Microsoft Entra SDK for AgentID" |
| 41 | |
| 42 | Verify request bodies and endpoints against the installed SDK version — Graph API shapes evolve. |
| 43 | |
| 44 | ## Conceptual Model |
| 45 | |
| 46 | ``` |
| 47 | Agent Identity Blueprint (application) ← one per agent type/project |
| 48 | └── BlueprintPrincipal (service principal) ← MUST be created explicitly |
| 49 | ├── Agent Identity (SP): agent-1 ← one per agent instance |
| 50 | ├── Agent Identity (SP): agent-2 |
| 51 | └── Agent Identity (SP): agent-3 |
| 52 | ``` |
| 53 | |
| 54 | | Concept | Description | |
| 55 | |---------|-------------| |
| 56 | | **Blueprint** | Application object that defines a type/class of agent. Holds credentials (secret, certificate, federated identity). | |
| 57 | | **BlueprintPrincipal** | Service principal for the Blueprint in the tenant. Not auto-created. | |
| 58 | | **Agent Identity** | Service-principal-only identity for a single agent instance. Cannot hold its own credentials. | |
| 59 | | **Sponsor** | A User (or Group, for Agent Identity) who is responsible for the identity. Required on creation. | |
| 60 | |
| 61 | ## Prerequisites |
| 62 | |
| 63 | ### Required Entra Roles |
| 64 | |
| 65 | One of: **Agent Identity Developer**, **Agent Identity Administrator**, or **Application Administrator**. |
| 66 | |
| 67 | ### PowerShell (interactive setup) |
| 68 | |
| 69 | ```powershell |
| 70 | # PowerShell 7+ |
| 71 | Install-Module Microsoft.Graph.Applications -Scope CurrentUser -Force |
| 72 | ``` |
| 73 | |
| 74 | ### Python (programmatic provisioning) |
| 75 | |
| 76 | ```bash |
| 77 | pip install azure-identity requests |
| 78 | ``` |
| 79 | |
| 80 | ## Authentication |
| 81 | |
| 82 | > **`DefaultAzureCredential` is not supported.** Azure CLI tokens carry `Directory.AccessAsUser.All`, which Agent Identity APIs hard-reject (403). Use a dedicated app registration with `client_credentials`, or `Connect-MgGraph` with explicit delegated scopes. |
| 83 | |
| 84 | ### PowerShell (delegated) |
| 85 | |
| 86 | ```powershell |
| 87 | Connect-MgGraph -Scopes @( |
| 88 | "AgentIdentityBlueprint.Create", |
| 89 | "AgentIdentityBlueprint.ReadWrite.All", |
| 90 | "AgentIdentityBlueprintPrincipal.Create", |
| 91 | "AgentIdentity.Create.All", |
| 92 | "User.Read" |
| 93 | ) |
| 94 | ``` |
| 95 | |
| 96 | ### Python (application) |
| 97 | |
| 98 | ```python |
| 99 | import os, requests |
| 100 | from azure.identity import ClientSecretCredential |
| 101 | |
| 102 | credential = ClientSecretCredential( |
| 103 | tenant_id=os.environ["AZURE_TENANT_ID"], |
| 104 | client_id=os.environ["AZURE_CLIENT_ID"], |
| 105 | client_secret=os.environ["AZURE_CLIENT_SECRET"], |
| 106 | ) |
| 107 | token = credential.get_token("https://graph.microsoft.com/.default") |
| 108 | |
| 109 | GRAPH = "https://graph.microsoft.com/v1.0" |
| 110 | headers = { |
| 111 | "Authorization": f"Bearer {token.token}", |
| 112 | "Content-Type": "application/json", |
| 113 | "OData-Version": "4.0", |
| 114 | } |
| 115 | ``` |
| 116 | |
| 117 | ## Core Workflow |
| 118 | |
| 119 | ### Step 1: Create Agent Identity Blueprint |
| 120 | |
| 121 | Use the typed endpoint. Sponsors must be **Users** at Blueprint creation. This snippet assumes the `requests` client and `headers` dict from the Python authentication block above. |
| 122 | |
| 123 | ```python |
| 124 | import subprocess |
| 125 | import requests |
| 126 | |
| 127 | user_id = subprocess.run( |
| 128 | ["az", "ad", "signed-in-user", "show", "--query", "id", "-o", "tsv"], |
| 129 | capture_output=True, text=True, check=True, |
| 130 | ).stdout.strip() |
| 131 | |
| 132 | blueprint_body = { |
| 133 | "displayName": "My Agent Blueprint", |
| 134 | "sponsors@odata.bind": [ |
| 135 | f"https://graph.microsoft.com/v1.0/users/{user_id}" |
| 136 | ], |
| 137 | } |
| 138 | resp = requests.post( |
| 139 | f"{GRAPH}/applications/microsoft.graph.agentIdentityBlueprint", |
| 140 | headers=headers, json=blueprint_body, |
| 141 | ) |
| 142 | resp.raise_for_status() |
| 143 | |
| 144 | blueprint = resp.json() |
| 145 | app_id = blueprint["appId"] |
| 146 | blueprint_obj_id = blueprint["id"] |
| 147 | ``` |
| 148 | |
| 149 | ### Step 2: Create BlueprintPrincipal |
| 150 | |
| 151 | > Mandatory. Creating a Blueprint does NOT auto-create its service principal. Skipping this step produces: |
| 152 | > `400: The Agent Blueprint Principal for the Agent Blueprint does not exist.` |
| 153 | |
| 154 | ```python |
| 155 | sp_body = {"appId": app_id} |
| 156 | resp = requests.post( |
| 157 | f"{GRAPH}/servicePrincipals/microsoft.graph.agentIdentityBlueprintPrincipal", |
| 158 | headers=headers, json=sp_body, |
| 159 | ) |
| 160 | resp.raise_for_status() |
| 161 | ``` |
| 162 | |
| 163 | Make your provisioning scripts idempotent — always check for the BlueprintPrincipal even when the Blueprint already exists. |
| 164 | |
| 165 | ### Step 3: Create Agent Identities |
| 166 | |
| 167 | Sponsors for an Agent Identity may be **Users or Groups**. |
| 168 | |
| 169 | ```python |
| 170 | agent_body = { |
| 171 | "displayName": "my-agent-instance-1", |
| 172 | "agentIdentityBlueprintId": app_id, |
| 173 | "sponsors@odata.bind": [ |
| 174 | f"https://graph.microsoft.com/v1.0/users/{user_id}" |
| 175 | ], |
| 176 | } |
| 177 | resp = requests.post( |
| 178 | f"{GRAPH}/servicePrincipals/microsoft.graph.agentIdentity", |
| 179 | headers=headers, json=agent_body, |
| 180 | ) |
| 181 | resp.raise_for_status() |
| 182 | agent = resp.json() |
| 183 | agent_sp_id = agent["id"] |
| 184 | ``` |
| 185 | |
| 186 | ## Runtime Authentication |
| 187 | |
| 188 | Agents authenticate at runtime using credentials configured on the **Blueprint** (not on the Agent Identity — Agent Identities can't hold credentials). |
| 189 | |
| 190 | | Option | Use case | Credential on Blueprint | |
| 191 | |--------|----------|------------------------| |
| 192 | | **Managed Identity + WIF** | Production (Azure-hosted) | Federated Identity Credential | |
| 193 | | **Client secret** | Local dev / testing | Password credential | |
| 194 | | **Microsoft Entra SDK for AgentID** | Polyglot / 3P agents | Sidecar container acquires tokens over HTTP | |
| 195 | |
| 196 | For the two-step `fmi_path` exchange (parent token → per-Agent-Identity Graph token) that gives each agent instance a distinct `sub` claim and audit trail, see [references/runtime-token-exchange.md](references/runtime-token-exchange.md). |
| 197 | |
| 198 | For OBO (agent acting on behalf of a user), see [references/obo-blueprint-setup.md](references/obo-blueprint-setup.md). |
| 199 | |
| 200 | For the containerized polyglot auth sidecar (Python, Node, Go, Java — no SDK embedding), see [references/sdk-sidecar.md](references/sdk-sidecar.md). |
| 201 | |
| 202 | For MI+WIF and client-secret setup details, see [references/oauth2-token-flow.md](references/oauth2-token-flow.md). |
| 203 | |
| 204 | ### .NET quick path |
| 205 | |
| 206 | For .NET services, use **`Microsoft.Identity.Web.AgentIdentities`** — it handles Federated Identity Credential management and the two-step exchange for you. See the package README at `github.com/AzureAD/microsoft-identity-web` under `src/Microsoft.Identity.Web.AgentIdentities/`. |
| 207 | |
| 208 | ## Granting Permissions (Per Agent Identity) |
| 209 | |
| 210 | Agent Identities support both application permissions (autonomous) and delegated permissions (OBO). Grants are scoped **per Agent Identity**, not to the BlueprintPrincipal. |
| 211 | |
| 212 | ### Application permissions (autonomous) |
| 213 | |
| 214 | ```python |
| 215 | graph_sp = requests.get( |
| 216 | f"{GRAPH}/servicePrincipals?$filter=appId eq '00000003-0000-0000-c000-000000000000'", |
| 217 | headers=headers, |
| 218 | ).json()["value"][0] |
| 219 | |
| 220 | user_read_all = next(r for r in graph_sp["appRoles"] if r["value"] == "User.Read.All") |
| 221 | |
| 222 | requests.post( |
| 223 | f"{GRAPH}/servicePrincipals/{agent_sp_id}/appRoleAssignments", |
| 224 | headers=headers, |
| 225 | json={ |
| 226 | "principalId": agent_sp_id, |
| 227 | "resourceId": graph_sp["id"], |
| 228 | "appRoleId": user_read_all["id"], |
| 229 | }, |
| 230 | ).raise_for_status() |
| 231 | ``` |
| 232 | |
| 233 | ### Delegated permissions (OBO) |
| 234 | |
| 235 | ```python |
| 236 | from datetime import datetime, timedelta, timezone |
| 237 | |
| 238 | expiry = (datetime.now(timezone.utc) + timedelta(days=3650)).strftime("%Y-%m-%dT%H:%M:%SZ") |
| 239 | |
| 240 | requests.post( |
| 241 | f"{GRAPH}/oauth2PermissionGrants", |
| 242 | headers=headers, |
| 243 | json={ |
| 244 | "clientId": agent_sp_id, |
| 245 | "consentType": "AllPrincipals", |
| 246 | "resourceId": graph_sp["id"], |
| 247 | "scope": "User.Read Tasks.ReadWrite Mail.Send", |
| 248 | "expiryTime": expiry, |
| 249 | }, |
| 250 | ).raise_for_status() |
| 251 | ``` |
| 252 | |
| 253 | Browser-based admin consent URLs do not work for Agent Identities — use `oauth2PermissionGrants` for programmatic delegated consent. |
| 254 | |
| 255 | ## Cross-Tenant Agent Identities |
| 256 | |
| 257 | Blueprints can be multi-tenant (`signInAudience: AzureADMultipleOrgs`). When exchanging tokens cross-tenant: |
| 258 | |
| 259 | > **Step 1 of the parent token exchange MUST target the Agent Identity's home tenant**, not the Blueprint's. Wrong tenant → `AADSTS700211: No matching federated identity record found`. |
| 260 | |
| 261 | See [references/runtime-token-exchange.md](references/runtime-token-exchange.md) for full cross-tenant examples. |
| 262 | |
| 263 | ## API Reference |
| 264 | |
| 265 | | Operation | Method | Endpoint | |
| 266 | |-----------|--------|----------| |
| 267 | | Create Blueprint | `POST` | `/applications/microsoft.graph.agentIdentityBlueprint` | |
| 268 | | Create BlueprintPrincipal | `POST` | `/servicePrincipals/microsoft.graph.agentIdentityBlueprintPrincipal` | |
| 269 | | Create Agent Identity | `POST` | `/servicePrincipals/microsoft.graph.agentIdentity` | |
| 270 | | Add FIC to Blueprint | `POST` | `/applications/{id}/microsoft.graph.agentIdentityBlueprint/federatedIdentityCredentials` | |
| 271 | | List Agent Identities | `GET` | `/servicePrincipals/microsoft.graph.agentIdentity` | |
| 272 | | Grant app permission | `POST` | `/servicePrincipals/{id}/appRoleAssignments` | |
| 273 | | Grant delegated permission | `POST` | `/oauth2PermissionGrants` | |
| 274 | | Delete Agent Identity | `DELETE` | `/servicePrincipals/{id}` | |
| 275 | | Delete Blueprint | `DELETE` | `/applications/{id}` | |
| 276 | |
| 277 | Base URL: `https://graph.microsoft.com/v1.0`. |
| 278 | |
| 279 | ## Required Graph Permissions |
| 280 | |
| 281 | | Permission | Purpose | |
| 282 | |-----------|---------| |
| 283 | | `AgentIdentityBlueprint.Create` | Create Blueprints | |
| 284 | | `AgentIdentityBlueprint.ReadWrite.All` | Read/update Blueprints | |
| 285 | | `AgentIdentityBlueprintPrincipal.Create` | Create BlueprintPrincipals | |
| 286 | | `AgentIdentity.Create.All` | Create Agent Identities | |
| 287 | | `AgentIdentity.ReadWrite.All` | Read/update Agent Identities | |
| 288 | | `Application.ReadWrite.All` | Blueprint CRUD on application objects | |
| 289 | | `AppRoleAssignment.ReadWrite.All` | Grant application permissions | |
| 290 | | `DelegatedPermissionGrant.ReadWrite.All` | Grant delegated permissions | |
| 291 | |
| 292 | Grant admin consent (required for application permissions): |
| 293 | |
| 294 | ```bash |
| 295 | az ad app permission admin-consent --id <client-id> |
| 296 | ``` |
| 297 | |
| 298 | After admin consent, tokens may not include new claims for 30–120 seconds — retry with exponential backoff. |
| 299 | |
| 300 | ## Best Practices |
| 301 | |
| 302 | 1. **Always create BlueprintPrincipal after Blueprint** — not auto-created. |
| 303 | 2. **Use typed endpoints** (`/applications/microsoft.graph.agentIdentityBlueprint`) instead of raw `/applications` with `@odata.type`. |
| 304 | 3. **Credentials live on the Blueprint** — Agent Identities can't hold secrets/certs (`PropertyNotCompatibleWithAgentIdentity`). |
| 305 | 4. **Include `OData-Version: 4.0`** on every Graph request. |
| 306 | 5. **Use Workload Identity Federation for production** — client secrets only for local dev. |
| 307 | 6. **Set `identifierUris: ["api://{appId}"]` on the Blueprint** before OAuth2 scope resolution. |
| 308 | 7. **Never use Azure CLI tokens** for Agent Identity APIs — `Directory.AccessAsUser.All` causes hard 403. |
| 309 | 8. **Use `fmi_path`** with `client_credentials` — NOT RFC 8693 `urn:ietf:params:oauth:grant-type:token-exchange` (returns `AADSTS82001`). |
| 310 | 9. **Always use `/.default` scope** in both steps of the exchange — individual scopes fail. |
| 311 | 10. **Step 1 targets the Agent Identity's home tenant** in cross-tenant flows. |
| 312 | 11. **Grant permissions per Agent Identity**, not to the BlueprintPrincipal. |
| 313 | 12. **Handle permission-propagation delays** — retry 403s with 30–120s backoff after admin consent. |
| 314 | 13. **Keep the Entra SDK for AgentID on localhost** — never expose via LoadBalancer or Ingress. |
| 315 | |
| 316 | ## Troubleshooting |
| 317 | |
| 318 | | Error | Cause | Fix | |
| 319 | |-------|-------|-----| |
| 320 | | `AADSTS82001` | Used RFC 8693 token-exchange grant | Use `client_credentials` with `fmi_path` | |
| 321 | | `AADSTS700211` | Step 1 parent token targeted wrong tenant | Target Agent Identity's home tenant | |
| 322 | | `AADSTS50013` | OBO user token targets Graph, not Blueprint | Use `api://{blueprint_app_id}/access_as_user` | |
| 323 | | `AADSTS65001` | Missing grant or used individual scopes | Use `/.default` and verify `oauth2PermissionGrants` | |
| 324 | | `403 Authorization_RequestDenied` | No grant on this Agent Identity | Add via `appRoleAssignments` or `oauth2PermissionGrants` | |
| 325 | | `PropertyNotCompatibleWithAgentIdentity` | Tried to add credential to Agent Identity SP | Put credentials on the Blueprint | |
| 326 | | `Agent Blueprint Principal does not exist` | BlueprintPrincipal not created | Step 2 of the Core Workflow | |
| 327 | | `AADSTS650051` on admin consent | SP already exists from partial consent | Grant directly via `appRoleAssignments` | |
| 328 | |
| 329 | ## References |
| 330 | |
| 331 | | File | Contents | |
| 332 | |------|----------| |
| 333 | | [references/runtime-token-exchange.md](references/runtime-token-exchange.md) | Two-step `fmi_path` exchange: autonomous + OBO, cross-tenant | |
| 334 | | [references/oauth2-token-flow.md](references/oauth2-token-flow.md) | MI + WIF (production) and client secret (local dev) | |
| 335 | | [references/obo-blueprint-setup.md](references/obo-blueprint-setup.md) | Configuring the Blueprint as an OAuth2 API for OBO | |
| 336 | | [references/sdk-sidecar.md](references/sdk-sidecar.md) | Microsoft Entra SDK for AgentID — architecture, configuration, endpoints | |
| 337 | | [references/sdk-sidecar-deployment.md](references/sdk-sidecar-deployment.md) | SDK code patterns (Python/TypeScript), Docker/Kubernetes manifests, security, troubleshooting | |
| 338 | | [references/known-limitations.md](references/known-limitations.md) | Documented gaps organized by category | |
| 339 | |
| 340 | ### External Links |
| 341 | |
| 342 | | Resource | URL | |
| 343 | |----------|-----| |
| 344 | | Agent ID Setup Guide | https://learn.microsoft.com/en-us/entra/agent-id/identity-platform/agent-id-setup-instructions | |
| 345 | | AI-Guided Setup | https://learn.microsoft.com/en-us/entra/agent-id/identity-platform/agent-id-ai-guided-setup | |
| 346 | | Microsoft Entra SDK for AgentID | https://learn.microsoft.com/en-us/entra/msidweb/agent-id-sdk/overview | |
| 347 | | Microsoft.Identity.Web.AgentIdentities (.NET) | https://github.com/AzureAD/microsoft-identity-web/blob/master/src/Microsoft.Identity.Web.AgentIdentities/README.AgentIdentities.md | |