ideabrowser.com — find trending startup ideas with real demand
Try itnpx skills add https://github.com/github/awesome-copilot --skill entra-agent-userAn agent user is a specialized user identity in Microsoft Entra ID that enables AI agents to act as digital workers. It allows agents to access APIs and services that strictly require user identities (e.g., Exchange mailboxes, Teams, org charts), while maintaining appropriate security boundaries.
Agent users receive tokens with idtyp=user, unlike regular agent identities which receive idtyp=app.
ServiceIdentity) created from an agent identity blueprintAgentIdUser.ReadWrite.IdentityParentedBy (least privileged)AgentIdUser.ReadWrite.AllUser.ReadWrite.AllImportant: The
identityParentIdmust reference a true agent identity (created via an agent identity blueprint), NOT a regular application service principal. You can verify by checking that the service principal has@odata.type: #microsoft.graph.agentIdentityandservicePrincipalType: ServiceIdentity.
Agent Identity Blueprint (application template)
│
├── Agent Identity (service principal - ServiceIdentity)
│ │
│ └── Agent User (user - agentUser) ← 1:1 relationship
│
└── Agent Identity Blueprint Principal (service principal in tenant)
| Component | Type | Token Claim | Purpose |
|---|---|---|---|
| Agent Identity | Service Principal | idtyp=app | Backend/API operations |
| Agent User | User (agentUser) | idtyp=user | Act as a digital worker in M365 |
Before creating an agent user, confirm the agent identity is a proper agentIdentity type:
GET https://graph.microsoft.com/beta/servicePrincipals/{agent-identity-id}
Authorization: Bearer <token>
Verify the response contains:
{
"@odata.type": "#microsoft.graph.agentIdentity",
"servicePrincipalType": "ServiceIdentity",
"agentIdentityBlueprintId": "<blueprint-id>"
}
Connect-MgGraph -Scopes "Application.Read.All" -TenantId "<tenant>" -UseDeviceCode -NoWelcome
Invoke-MgGraphRequest -Method GET `
-Uri "https://graph.microsoft.com/beta/servicePrincipals/<agent-identity-id>" | ConvertTo-Json -Depth 3
Common mistake: Using an app registration's
appIdor a regular application service principal'sidwill fail. Only agent identities created from blueprints work.
POST https://graph.microsoft.com/beta/users/microsoft.graph.agentUser
Content-Type: application/json
Authorization: Bearer <token>
{
"accountEnabled": true,
"displayName": "My Agent User",
"mailNickname": "my-agent-user",
"userPrincipalName": "my-agent-user@yourtenant.onmicrosoft.com",
"identityParentId": "<agent-identity-object-id>"
}
| Property | Type | Description |
|---|---|---|
accountEnabled | Boolean | true to enable the account |
displayName | String | Human-friendly name |
mailNickname | String | Mail alias (no spaces/special chars) |
userPrincipalName | String | UPN — must be unique in the tenant (alias@verified-domain) |
identityParentId | String | Object ID of the parent agent identity |
Connect-MgGraph -Scopes "User.ReadWrite.All" -TenantId "<tenant>" -UseDeviceCode -NoWelcome
$body = @{
accountEnabled = $true
displayName = "My Agent User"
mailNickname = "my-agent-user"
userPrincipalName = "my-agent-user@yourtenant.onmicrosoft.com"
identityParentId = "<agent-identity-object-id>"
} | ConvertTo-Json
Invoke-MgGraphRequest -Method POST `
-Uri "https://graph.microsoft.com/beta/users/microsoft.graph.agentUser" `
-Body $body -ContentType "application/json" | ConvertTo-Json -Depth 3
400 Bad Request.userPrincipalName must be unique. Don't reuse an existing user's UPN.Assigning a manager allows the agent user to appear in org charts (e.g., Teams).
PUT https://graph.microsoft.com/beta/users/{agent-user-id}/manager/$ref
Content-Type: application/json
Authorization: Bearer <token>
{
"@odata.id": "https://graph.microsoft.com/beta/users/{manager-user-id}"
}
$managerBody = '{"@odata.id":"https://graph.microsoft.com/beta/users/<manager-user-id>"}'
Invoke-MgGraphRequest -Method PUT `
-Uri "https://graph.microsoft.com/beta/users/<agent-user-id>/manager/`$ref" `
-Body $managerBody -ContentType "application/json"
A license is needed for the agent user to have a mailbox, Teams presence, etc. Usage location must be set first.
PATCH https://graph.microsoft.com/beta/users/{agent-user-id}
Content-Type: application/json
Authorization: Bearer <token>
{
"usageLocation": "US"
}
GET https://graph.microsoft.com/beta/subscribedSkus?$select=skuPartNumber,skuId,consumedUnits,prepaidUnits
Authorization: Bearer <token>
Requires Organization.Read.All permission.
POST https://graph.microsoft.com/beta/users/{agent-user-id}/assignLicense
Content-Type: application/json
Authorization: Bearer <token>
{
"addLicenses": [
{ "skuId": "<sku-id>" }
],
"removeLicenses": []
}
Connect-MgGraph -Scopes "User.ReadWrite.All","Organization.Read.All" -TenantId "<tenant>" -NoWelcome
# Set usage location
Invoke-MgGraphRequest -Method PATCH `
-Uri "https://graph.microsoft.com/beta/users/<agent-user-id>" `
-Body '{"usageLocation":"US"}' -ContentType "application/json"
# Assign license
$licenseBody = '{"addLicenses":[{"skuId":"<sku-id>"}],"removeLicenses":[]}'
Invoke-MgGraphRequest -Method POST `
-Uri "https://graph.microsoft.com/beta/users/<agent-user-id>/assignLicense" `
-Body $licenseBody -ContentType "application/json"
Tip: You can also assign licenses via the Entra admin center under Identity → Users → All users → select the agent user → Licenses and apps.
| Service | Estimated Time |
|---|---|
| Exchange mailbox | 5–30 minutes |
| Teams availability | 15 min – 24 hours |
| Org chart / People search | Up to 24–48 hours |
| SharePoint / OneDrive | 5–30 minutes |
| Global Address List | Up to 24 hours |
idtyp=user tokens)| Error | Cause | Fix |
|---|---|---|
Agent user IdentityParent does not exist | identityParentId points to a non-existent or non-agent-identity object | Verify the ID is an agentIdentity service principal, not a regular app |
400 Bad Request (identityParentId already linked) | The agent identity already has an agent user | Each agent identity supports only one agent user |
409 Conflict on UPN | The userPrincipalName is already taken | Use a unique UPN |
| License assignment fails | Usage location not set | Set usageLocation before assigning licenses |