Skip to content

Commit 34dddbd

Browse files
authored
Merge pull request #188 from ArLucaID/skill/entra-agent-id
Add entra-agent-id skill for Microsoft Entra Agent ID (preview)
2 parents e27a688 + cdb4bfc commit 34dddbd

File tree

6 files changed

+1037
-5
lines changed

6 files changed

+1037
-5
lines changed
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
---
2+
name: entra-agent-id
3+
description: |
4+
Microsoft Entra Agent ID (preview) for creating OAuth2-capable AI agent identities via Microsoft Graph beta API.
5+
Covers Agent Identity Blueprints, BlueprintPrincipals, Agent Identities, required permissions, sponsors, and Workload Identity Federation.
6+
Triggers: "agent identity", "agent id", "Agent Identity Blueprint", "BlueprintPrincipal", "entra agent", "agent identity provisioning", "Graph agent identity".
7+
---
8+
9+
# Microsoft Entra Agent ID
10+
11+
Create and manage OAuth2-capable identities for AI agents using Microsoft Graph beta API.
12+
13+
> **Preview API** — All Agent Identity endpoints are under `/beta` only. Not available in `/v1.0`.
14+
15+
## Before You Start
16+
17+
Search `microsoft-docs` MCP for the latest Agent ID documentation:
18+
- Query: "Microsoft Entra agent identity setup"
19+
- Verify: API parameters match current preview behavior
20+
21+
## Conceptual Model
22+
23+
```
24+
Agent Identity Blueprint (application) ← one per agent type/project
25+
└── BlueprintPrincipal (service principal) ← MUST be created explicitly
26+
├── Agent Identity (SP): agent-1 ← one per agent instance
27+
├── Agent Identity (SP): agent-2
28+
└── Agent Identity (SP): agent-3
29+
```
30+
31+
## Prerequisites
32+
33+
### PowerShell (recommended for interactive setup)
34+
35+
```powershell
36+
# Requires PowerShell 7+
37+
Install-Module Microsoft.Graph.Beta.Applications -Scope CurrentUser -Force
38+
```
39+
40+
### Python (for programmatic provisioning)
41+
42+
```bash
43+
pip install azure-identity requests
44+
```
45+
46+
### Required Entra Roles
47+
48+
One of: **Agent Identity Developer**, **Agent Identity Administrator**, or **Application Administrator**.
49+
50+
## Environment Variables
51+
52+
```bash
53+
AZURE_TENANT_ID=<your-tenant-id>
54+
AZURE_CLIENT_ID=<app-registration-client-id>
55+
AZURE_CLIENT_SECRET=<app-registration-secret>
56+
```
57+
58+
## Authentication
59+
60+
> **⚠️ `DefaultAzureCredential` is NOT supported.** Azure CLI tokens contain
61+
> `Directory.AccessAsUser.All`, which Agent Identity APIs explicitly reject (403).
62+
> You MUST use a dedicated app registration with `client_credentials` flow or
63+
> connect via `Connect-MgGraph` with explicit delegated scopes.
64+
65+
### PowerShell (delegated permissions)
66+
67+
```powershell
68+
Connect-MgGraph -Scopes @(
69+
"AgentIdentityBlueprint.Create",
70+
"AgentIdentityBlueprint.ReadWrite.All",
71+
"AgentIdentityBlueprintPrincipal.Create",
72+
"User.Read"
73+
)
74+
Set-MgRequestContext -ApiVersion beta
75+
76+
$currentUser = (Get-MgContext).Account
77+
$userId = (Get-MgUser -UserId $currentUser).Id
78+
```
79+
80+
### Python (application permissions)
81+
82+
```python
83+
import os
84+
import requests
85+
from azure.identity import ClientSecretCredential
86+
87+
credential = ClientSecretCredential(
88+
tenant_id=os.environ["AZURE_TENANT_ID"],
89+
client_id=os.environ["AZURE_CLIENT_ID"],
90+
client_secret=os.environ["AZURE_CLIENT_SECRET"],
91+
)
92+
token = credential.get_token("https://graph.microsoft.com/.default")
93+
94+
GRAPH = "https://graph.microsoft.com/beta"
95+
headers = {
96+
"Authorization": f"Bearer {token.token}",
97+
"Content-Type": "application/json",
98+
"OData-Version": "4.0", # Required for all Agent Identity API calls
99+
}
100+
```
101+
102+
## Core Workflow
103+
104+
### Step 1: Create Agent Identity Blueprint
105+
106+
Sponsors are required and **must be User objects** — ServicePrincipals and Groups are rejected.
107+
108+
```python
109+
import subprocess
110+
111+
# Get sponsor user ID (client_credentials has no user context, so use az CLI)
112+
result = subprocess.run(
113+
["az", "ad", "signed-in-user", "show", "--query", "id", "-o", "tsv"],
114+
capture_output=True, text=True, check=True,
115+
)
116+
user_id = result.stdout.strip()
117+
118+
blueprint_body = {
119+
"@odata.type": "Microsoft.Graph.AgentIdentityBlueprint",
120+
"displayName": "My Agent Blueprint",
121+
"sponsors@odata.bind": [
122+
f"https://graph.microsoft.com/beta/users/{user_id}"
123+
],
124+
}
125+
resp = requests.post(f"{GRAPH}/applications", headers=headers, json=blueprint_body)
126+
resp.raise_for_status()
127+
128+
blueprint = resp.json()
129+
app_id = blueprint["appId"]
130+
blueprint_obj_id = blueprint["id"]
131+
```
132+
133+
### Step 2: Create BlueprintPrincipal
134+
135+
> **This step is mandatory.** Creating a Blueprint does NOT auto-create its
136+
> service principal. Without this, Agent Identity creation fails with:
137+
> `400: The Agent Blueprint Principal for the Agent Blueprint does not exist.`
138+
139+
```python
140+
sp_body = {
141+
"@odata.type": "Microsoft.Graph.AgentIdentityBlueprintPrincipal",
142+
"appId": app_id,
143+
}
144+
resp = requests.post(f"{GRAPH}/servicePrincipals", headers=headers, json=sp_body)
145+
resp.raise_for_status()
146+
```
147+
148+
If implementing idempotent scripts, check for and create the BlueprintPrincipal
149+
even when the Blueprint already exists (a previous run may have created the Blueprint
150+
but crashed before creating the SP).
151+
152+
### Step 3: Create Agent Identities
153+
154+
```python
155+
agent_body = {
156+
"@odata.type": "Microsoft.Graph.AgentIdentity",
157+
"displayName": "my-agent-instance-1",
158+
"agentIdentityBlueprintId": app_id,
159+
"sponsors@odata.bind": [
160+
f"https://graph.microsoft.com/beta/users/{user_id}"
161+
],
162+
}
163+
resp = requests.post(f"{GRAPH}/servicePrincipals", headers=headers, json=agent_body)
164+
resp.raise_for_status()
165+
agent = resp.json()
166+
```
167+
168+
## API Reference
169+
170+
| Operation | Method | Endpoint | OData Type |
171+
|-----------|--------|----------|------------|
172+
| Create Blueprint | `POST` | `/applications` | `Microsoft.Graph.AgentIdentityBlueprint` |
173+
| Create BlueprintPrincipal | `POST` | `/servicePrincipals` | `Microsoft.Graph.AgentIdentityBlueprintPrincipal` |
174+
| Create Agent Identity | `POST` | `/servicePrincipals` | `Microsoft.Graph.AgentIdentity` |
175+
| List Agent Identities | `GET` | `/servicePrincipals?$filter=...` ||
176+
| Delete Agent Identity | `DELETE` | `/servicePrincipals/{id}` ||
177+
| Delete Blueprint | `DELETE` | `/applications/{id}` ||
178+
179+
All endpoints use base URL: `https://graph.microsoft.com/beta`
180+
181+
## Required Permissions
182+
183+
| Permission | Purpose |
184+
|-----------|---------|
185+
| `Application.ReadWrite.All` | Blueprint CRUD (application objects) |
186+
| `AgentIdentityBlueprint.Create` | Create new Blueprints |
187+
| `AgentIdentityBlueprint.ReadWrite.All` | Read/update Blueprints |
188+
| `AgentIdentityBlueprintPrincipal.Create` | Create BlueprintPrincipals |
189+
| `AgentIdentity.Create.All` | Create Agent Identities |
190+
| `AgentIdentity.ReadWrite.All` | Read/update Agent Identities |
191+
192+
There are **18 Agent Identity-specific** Graph application permissions. Discover all:
193+
```bash
194+
az ad sp show --id 00000003-0000-0000-c000-000000000000 \
195+
--query "appRoles[?contains(value, 'AgentIdentity')].{id:id, value:value}" -o json
196+
```
197+
198+
Grant admin consent (required for application permissions):
199+
```bash
200+
az ad app permission admin-consent --id <client-id>
201+
```
202+
203+
> Admin consent may fail with 404 if the service principal hasn't replicated. Retry with 10–40s backoff.
204+
205+
## Cleanup
206+
207+
```python
208+
# Delete Agent Identity
209+
requests.delete(f"{GRAPH}/servicePrincipals/{agent['id']}", headers=headers)
210+
211+
# Delete BlueprintPrincipal (get SP ID first)
212+
sps = requests.get(
213+
f"{GRAPH}/servicePrincipals?$filter=appId eq '{app_id}'",
214+
headers=headers,
215+
).json()
216+
for sp in sps.get("value", []):
217+
requests.delete(f"{GRAPH}/servicePrincipals/{sp['id']}", headers=headers)
218+
219+
# Delete Blueprint
220+
requests.delete(f"{GRAPH}/applications/{blueprint_obj_id}", headers=headers)
221+
```
222+
223+
## Best Practices
224+
225+
1. **Always create BlueprintPrincipal after Blueprint** — not auto-created; implement idempotent checks on both
226+
2. **Use User objects as sponsors** — ServicePrincipals and Groups are rejected
227+
3. **Handle permission propagation delays** — after admin consent, wait 30–120s; retry with backoff on 403
228+
4. **Include `OData-Version: 4.0` header** on every Graph request
229+
5. **Use Workload Identity Federation for production auth** — for local dev, use a client secret on the Blueprint (see [references/oauth2-token-flow.md](references/oauth2-token-flow.md))
230+
6. **Set `identifierUris` on Blueprint** before using OAuth2 scoping (`api://{app-id}`)
231+
7. **Never use Azure CLI tokens** for API calls — they contain `Directory.AccessAsUser.All` which is hard-rejected
232+
8. **Check for existing resources** before creating — implement idempotent provisioning
233+
234+
## References
235+
236+
| File | Contents |
237+
|------|----------|
238+
| [references/oauth2-token-flow.md](references/oauth2-token-flow.md) | Production (Managed Identity + WIF) and local dev (client secret) token flows |
239+
| [references/known-limitations.md](references/known-limitations.md) | 29 known issues organized by category (from official preview known-issues page) |
240+
241+
### External Links
242+
243+
| Resource | URL |
244+
|----------|-----|
245+
| Official Setup Guide | https://learn.microsoft.com/en-us/entra/agent-id/identity-platform/agent-id-setup-instructions |
246+
| AI-Guided Setup | https://learn.microsoft.com/en-us/entra/agent-id/identity-platform/agent-id-ai-guided-setup |

0 commit comments

Comments
 (0)