All skills
microsoft avatar

/entra-agent-id

@b3c238e
by microsoftmicrosoft/skills3.1k stars
351

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).

Use this Skill: https://skilld.dev/gh/microsoft/skills/entra-agent-id

This session only. Nothing lands on disk.

referencesoauth2-token-flow.md

≈1.1k tokens on demand. Your agent reads this file only when SKILL.md points to it.

OAuth2 Token Flow

Source: Agent ID Setup Instructions

Agent Identities authenticate at runtime using credentials configured on the Blueprint (not on the Agent Identity — Agent Identities cannot hold credentials).

Option Use case Credential type
Managed Identity + WIF Production (Azure-hosted) Federated Identity Credential on Blueprint
Client secret Local dev / testing Password credential on Blueprint

Both options feed the two-step fmi_path exchange in runtime-token-exchange.md.


Option A: Managed Identity + Workload Identity Federation (Production)

1. Set the Application ID URI on the Blueprint

requests.patch(
    f"{GRAPH}/applications/{blueprint_obj_id}",
    headers=headers,
    json={"identifierUris": [f"api://{blueprint_app_id}"]},
).raise_for_status()

2. Create a Federated Identity Credential on the Blueprint

Use the typed path — FICs go on the Blueprint, not on the Agent Identity SP:

fic_body = {
    "name": "my-fic-name",
    "issuer": f"https://login.microsoftonline.com/{tenant_id}/v2.0",
    "subject": mi_principal_id,   # The MI's object ID (principalId), NOT client ID
    "audiences": ["api://AzureADTokenExchange"],
}
requests.post(
    f"{GRAPH}/applications/{blueprint_obj_id}"
    f"/microsoft.graph.agentIdentityBlueprint/federatedIdentityCredentials",
    headers=headers, json=fic_body,
).raise_for_status()

3. Acquire a token from the caller

from azure.identity import ManagedIdentityCredential

cred = ManagedIdentityCredential(client_id=MI_CLIENT_ID)
token = cred.get_token(f"api://{blueprint_app_id}/.default")
# Authorization: Bearer {token.token}

4. Validate on the backend

import jwt
from jwt import PyJWKClient

jwks_client = PyJWKClient(
    f"https://login.microsoftonline.com/{tenant_id}/discovery/v2.0/keys"
)
signing_key = jwks_client.get_signing_key_from_jwt(token_str)

claims = jwt.decode(
    token_str,
    signing_key.key,
    algorithms=["RS256"],
    audience=f"api://{blueprint_app_id}",
    issuer=f"https://sts.windows.net/{tenant_id}/",
)

Key Rules (WIF)

  • FICs go on the Blueprint using the typed path (.../microsoft.graph.agentIdentityBlueprint/federatedIdentityCredentials).
  • subject is the MI's principalId (object ID), not its client ID.
  • audiences must be ["api://AzureADTokenExchange"] — not your API audience.
  • FIC issuer: https://login.microsoftonline.com/{tenant}/v2.0.
  • Token issuer for validation: https://sts.windows.net/{tenant}/ (different domain, trailing slash).

Option B: Client Secret (Local Dev)

1. Add a password credential to the Blueprint

PowerShell:

$body = @{
    "passwordCredential" = @{
        "displayName" = "Dev Secret"
        "endDateTime" = "2027-01-01T00:00:00Z"
    }
}

$credential = Invoke-MgGraphRequest -Method POST `
    -Uri "https://graph.microsoft.com/v1.0/applications/<BLUEPRINT_OBJECT_ID>/addPassword" `
    -Headers @{ "OData-Version" = "4.0"; "Content-Type" = "application/json" } `
    -Body ($body | ConvertTo-Json -Depth 5) -OutputType PSObject

$credential.secretText   # Save NOW — not retrievable later

Python:

resp = requests.post(
    f"{GRAPH}/applications/{blueprint_obj_id}/addPassword",
    headers=headers,
    json={"passwordCredential": {
        "displayName": "Dev Secret",
        "endDateTime": "2027-01-01T00:00:00Z",
    }},
)
resp.raise_for_status()
secret_text = resp.json()["secretText"]   # Save NOW

2. Drive the two-step exchange

Pass blueprint_secret=secret_text into get_parent_token(...) from runtime-token-exchange.md, then call exchange_autonomous or exchange_obo.

Key Rules (Client Secret)

  • Save secretText immediately — it can't be retrieved later.
  • Secrets belong on the Blueprint only — Agent Identities can't have password credentials (PropertyNotCompatibleWithAgentIdentity).
  • Not for production — use MI + WIF.
  • Respect org credential-lifetime policy when setting endDateTime.
  • Don't use DefaultAzureCredential to acquire Blueprint tokens — Azure CLI tokens carry Directory.AccessAsUser.All and are rejected. Use ClientSecretCredential or the raw HTTP exchange.

Source: SKILL.md on GitHub

1 warning17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    This skill facilitates the management of Microsoft Entra Agent IDs using official Microsoft tools and APIs. It includes important considerations for handling Azure credentials and provides guidance on transitioning from local development secrets to production-grade authentication methods.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer6mo

    4/4 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at b3c238e. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 20 hours ago.

Activeupdated 2 months ago
metadata
{
  "author": "Microsoft",
  "version": "1.1.1"
}

README badge

README badge for microsoft/skills/entra-agent-id