Azure-Workloads authentifizieren sich bei der Claude API, indem sie ein von Microsoft Entra ID ausgestelltes JSON Web Token (JWT) vorlegen und es dann gegen ein kurzlebiges Anthropic-Zugriffstoken eintauschen. Die Einrichtung folgt auf jeder Azure-Plattform demselben Muster:
POST /v1/oauth/token gegen ein sk-ant-oat01-... Anthropic-Zugriffstoken ein und ruft damit Claude auf.Auf beiden Pfaden trägt das Token, das du Anthropic vorlegst, deinen tenant-spezifischen Entra-Issuer und die Objekt-ID der Managed Identity in den Claims sub und oid; nur wie der Workload dieses Token erhält, unterscheidet sich. Wähle den Abschnitt für den Ort, an dem dein Workload läuft: Eine Managed Identity verwenden für VMs, VM Scale Sets, App Service, Functions oder Container Apps; Entra Workload Identity auf AKS verwenden für AKS.
Microsoft Entra ID stellt ein Token nur aus, wenn die angeforderte Audience in deinem Tenant als App-Registrierung mit einem Service Principal existiert. Erstelle eine App-Registrierung, die die Claude API-Audience repräsentiert; jeder Workload im Tenant kann Tokens dafür anfordern. Ohne diese Registrierung schlagen Token-Anfragen mit einem „resource not found in tenant"-Fehler fehl (AADSTS50001 von den Managed-Identity-Endpunkten, AADSTS500011 vom Entra-Token-Endpunkt).
# Erstelle die App-Registrierung, die die Claude API-Audience repräsentiert.
APP_ID=$(az ad app create --display-name claude-api-federation --query appId -o tsv)
# Fordere v2.0-Access-Tokens an und setze die Identifier-URI api://<APP_ID>.
az ad app update --id "$APP_ID" \
--identifier-uris "api://$APP_ID" \
--set api.requestedAccessTokenVersion=2
# Erstelle den Service Principal, damit die Audience in deinem Tenant aufgelöst wird.
az ad sp create --id "$APP_ID"Verwende das Identifier-URI-Format api://<APP_ID>. Entra beschränkt https://-Identifier-URIs auf verifizierte Domains deines eigenen Tenants, sodass eine URI wie https://api.anthropic.com in den meisten Tenants nicht registriert werden kann; api://<APP_ID> wird überall akzeptiert. Mit requestedAccessTokenVersion: 2 sind Tokens für diese Audience v2.0, wovon dieser Leitfaden ausgeht. Wenn du eine bestehende Registrierung wiederverwendest, die v1.0-Tokens ausgibt, siehe Wenn deine Tokens v1.0 sind.
Verwende diesen Pfad, wenn dein Workload auf einer VM, einem VM Scale Set, App Service, Functions oder Container Apps läuft. Der Workload fordert ein von Entra ausgestelltes JWT für seine zugewiesene Managed Identity vom lokalen Token-Endpunkt der Plattform an und tauscht dieses JWT dann bei Anthropic ein.
Eine Managed Identity anhängen
Aktiviere eine systemseitig zugewiesene oder benutzerseitig zugewiesene Managed Identity auf deiner Azure-Ressource. Öffne im Azure-Portal die Ressource, gehe zu Identity und aktiviere System assigned (oder hänge eine benutzerseitig zugewiesene Identität an).
Nachdem die Identität erstellt wurde, notiere ihre Object (principal) ID. Diese GUID erscheint sowohl als sub- als auch als oid-Claim im ausgestellten Token, und deine Anthropic-Föderationsregel wird darauf matchen. Du findest sie auf der Identity-Seite der Ressource; für eine benutzerseitig zugewiesene Identität ist es die Object (principal) ID auf der Overview-Seite der Managed-Identity-Ressource. (Eine Managed Identity hat in Microsoft Entra ID nur einen Service Principal, keine App-Registrierung.)
Den Token-Endpunkt der Plattform finden
Die Plattform stellt einen lokalen Token-Endpunkt bereit, sobald die Identität angehängt ist:
http://169.254.169.254/metadata/identity/oauth2/token mit dem Header Metadata: true und api-version=2018-02-01.IDENTITY_ENDPOINT mit dem Header X-IDENTITY-HEADER, gesetzt auf den Wert von IDENTITY_HEADER, und api-version=2019-08-01. IMDS ist auf diesen Plattformen nicht erreichbar.Wenn die Ressource mehr als eine benutzerseitig zugewiesene Managed Identity hat, füge client_id=<IDENTITY_CLIENT_ID> zur Token-Anfrage hinzu, um eine auszuwählen. Azure empfiehlt, sie immer anzugeben. Ohne sie hängt das Ergebnis davon ab, ob die Ressource auch eine systemseitig zugewiesene Identität aktiviert hat: Wenn ja, fällt die Anfrage stillschweigend auf diese Identität zurück und scheitert dann am oid-Match deiner Föderationsregel; wenn nicht, schlägt die Anfrage sofort fehl, sobald eine zweite benutzerseitig zugewiesene Identität angehängt wird.
Ein Beispiel-Token dekodieren
Fordere ein Token vom Endpunkt an und dekodiere seine Payload, um die Claims zu bestätigen, auf die deine Föderationsregel matchen muss. (Für den Dekodierbefehl siehe Einen fehlgeschlagenen Austausch beheben.) Ein v2.0-Token für eine Managed Identity trägt diese Claims:
{
"iss": "https://login.microsoftonline.com/<TENANT_ID>/v2.0",
"sub": "9f8e7d6c-1a2b-3c4d-5e6f-...",
"aud": "<APP_ID>",
"oid": "9f8e7d6c-1a2b-3c4d-5e6f-...",
"tid": "<TENANT_ID>",
"azp": "<IDENTITY_CLIENT_ID>",
"ver": "2.0",
"exp": 1775527120
}| Claim | Wert | Matche darauf, wenn |
|---|---|---|
oid | Die Objekt-ID der Managed Identity, identisch mit sub | Du eine bestimmte Managed Identity autorisieren möchtest. Dies ist der Standard; die Regel in Konfiguriere Anthropic matcht darauf. |
azp | Die Client-ID der aufrufenden Identität | Du jeden Workload autorisieren möchtest, der sich eine App-Registrierung teilt. Für eine Managed Identity ist azp für diese Identität eindeutig und damit äquivalent zu oid. |
aud | Die Client-ID der Audience-App-Registrierung (die <APP_ID>-GUID aus Registriere die Token-Audience) | Immer. Das audience-Feld der Regel muss exakt dem aud-Wert des Tokens entsprechen. |
tid | Deine Tenant-ID | Du Defense in Depth möchtest. Die Issuer-URL legt den Tenant bereits fest. |
Wenn der ver-Claim des dekodierten Tokens 1.0 ist, unterscheiden sich die Claim-Namen und -Werte. Siehe Wenn deine Tokens v1.0 sind, bevor du fortfährst.
Öffne in der Claude Console Settings → Workload identity, klicke auf Connect workload und wähle die Kachel Microsoft Entra. Der Assistent führt dich durch die Registrierung des Issuers, die Erstellung eines Service-Kontos und die Erstellung einer Föderationsregel.
Der Assistent erstellt diese Ressourcen für dich. Verwende die folgenden Werte, unabhängig davon, ob du sie im Assistenten eingibst oder an die Admin API sendest:
Föderations-Issuer: Wähle v2.0 (login.microsoftonline.com) im Token issuer-Selektor des Assistenten. (Der Selektor steht standardmäßig auf v1; dieser Standard existiert für Tenants, die ältere Registrierungen wiederverwenden, die noch v1.0-Tokens ausgeben.) Entra veröffentlicht ein OIDC-Discovery-Dokument unter der tenant-spezifischen Issuer-URL, verwende also den Discovery-Modus. Jeder Microsoft Entra-Tenant, den du föderierst, benötigt einen eigenen Issuer-Eintrag.
{
"name": "azure-prod-tenant",
"issuer_url": "https://login.microsoftonline.com/<TENANT_ID>/v2.0",
"jwks": { "type": "discovery" },
"max_jwt_lifetime_seconds": 86400
}Managed-Identity-Workloads benötigen max_jwt_lifetime_seconds: 86400. Azure stellt Managed-Identity-Tokens mit bis zu 24 Stunden zwischen iat und exp aus, weil es das Token jeder Ressource für dieses Zeitfenster zwischenspeichert und keine Möglichkeit bietet, eine vorzeitige Aktualisierung zu erzwingen, und der 1-Stunden-Standard des Issuers lehnt diese Tokens mit invalid_grant ab. Die Microsoft Entra-Kachel des Connect-workload-Assistenten erstellt den Issuer mit max_jwt_lifetime_seconds auf 7500 gesetzt und bietet während der Erstellung kein Feld, um dies zu ändern. Schließe also den Assistenten ab, öffne dann Settings → Workload identity → Issuers, bearbeite den Issuer und erhöhe den Wert auf 86400. Du kannst den Issuer auch über die Admin API aktualisieren.
Eine längere akzeptierte Lebensdauer bedeutet, dass ein geleaktes Entra-Token länger eintauschbar bleibt. Wenn ein Token leakt, ist der Hebel das Deaktivieren der Föderationsregel; ein enger oid-Match begrenzt von vornherein, welche Identitäten ein Token eintauschen können, wie in Begrenze den Geltungsbereich deiner Regel beschrieben.
Föderationsregel: Matche auf die Objekt-ID der Managed Identity und deine Tenant-ID. Für die v2.0-Tokens, die dieser Leitfaden konfiguriert, ist der audience-Wert die Client-ID der Audience-App-Registrierung (die <APP_ID>-GUID aus Registriere die Token-Audience). Verwende den exakten aud-Wert aus deinem dekodierten Token.
{
"name": "azure-inference-worker",
"issuer_id": "fdis_...",
"match": {
"audience": "<APP_ID>",
"claims": {
"oid": "9f8e7d6c-1a2b-3c4d-5e6f-...",
"tid": "<TENANT_ID>"
}
},
"target": {
"type": "service_account",
"service_account_id": "svac_..."
},
"workspace_id": "wrkspc_...",
"oauth_scope": "workspace:developer",
"token_lifetime_seconds": 600
}token_lifetime_seconds ist die Lebensdauer des Anthropic-Zugriffstokens, das der Austausch zurückgibt, nicht die des Entra-Tokens; das SDK aktualisiert es für dich.
Zur Laufzeit holt dein Workload sein Entra-Token, tauscht es unter POST /v1/oauth/token ein und verwendet das zurückgegebene Bearer-Token, um Claude aufzurufen. Jedes Anthropic SDK übernimmt den Austausch und die Aktualisierungsschleife, wenn du ein Token-Provider-Callable bereitstellst, wie in den folgenden Beispielen gezeigt. Der cURL-Tab zeigt den rohen Ablauf.
Die Beispiele holen das Managed-Identity-Token vom Token-Endpunkt der Plattform: IMDS auf VMs und VM Scale Sets oder der IDENTITY_ENDPOINT-Dienst auf App Service, Functions und Container Apps. Ersetze <APP_ID> im api://<APP_ID>-Ressourcenwert durch die Client-ID der Audience-App-Registrierung aus Registriere die Token-Audience.
Wenn dein Workload bereits die Azure Identity-Clientbibliothek verwendet, übergib deren Token-Beschaffung (DefaultAzureCredential mit dem Scope api://<APP_ID>/.default) als Identity-Token-Provider, anstatt die Token-Endpunkte direkt aufzurufen. Die Bibliothek wählt auf jeder Azure-Plattform den richtigen Endpunkt aus, einschließlich AKS mit Entra Workload Identity.
import os
import anthropic
import requests
from anthropic import WorkloadIdentityCredentials
# Der Identifier-URI der Audience-App-Registrierung (siehe "Token-Audience registrieren").
AUDIENCE = "api://<APP_ID>"
def fetch_entra_token() -> str:
"""Fetch a managed identity token from the platform's token endpoint."""
# Bei mehreren benutzerzugewiesenen Identitäten füge client_id=<IDENTITY_CLIENT_ID>
# zu den Request-Parametern hinzu, um eine auszuwählen.
if endpoint := os.environ.get("IDENTITY_ENDPOINT"):
# App Service, Functions, Container Apps
response = requests.get(
endpoint,
headers={"X-IDENTITY-HEADER": os.environ["IDENTITY_HEADER"]},
params={"api-version": "2019-08-01", "resource": AUDIENCE},
timeout=5,
)
else:
# VM oder VM Scale Set: Azure Instance Metadata Service (IMDS)
response = requests.get(
"http://169.254.169.254/metadata/identity/oauth2/token",
headers={"Metadata": "true"},
params={"api-version": "2018-02-01", "resource": AUDIENCE},
timeout=5,
)
response.raise_for_status()
return response.json()["access_token"]
client = anthropic.Anthropic(
credentials=WorkloadIdentityCredentials(
identity_token_provider=fetch_entra_token,
federation_rule_id=os.environ["ANTHROPIC_FEDERATION_RULE_ID"],
organization_id=os.environ["ANTHROPIC_ORGANIZATION_ID"],
service_account_id=os.environ["ANTHROPIC_SERVICE_ACCOUNT_ID"],
workspace_id=os.environ.get("ANTHROPIC_WORKSPACE_ID"),
),
)
message = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello from Azure"}],
)
print(next(block.text for block in message.content if block.type == "text"))Führe von deiner Azure-Ressource aus den in Token beziehen und verwenden gezeigten cURL-Austausch aus und bestätige, dass POST /v1/oauth/token eine 200 mit einem access_token, das mit sk-ant-oat01- beginnt, und einem expires_in-Wert in Sekunden zurückgibt. Bei 400 invalid_grant dekodiere das Entra-Token (siehe Einen fehlgeschlagenen Austausch beheben für den Befehl) und prüfe die häufigsten Azure-seitigen Ursachen:
issuer_url muss exakt mit dem iss-Claim des Tokens übereinstimmen. Ein v2.0-Token trägt https://login.microsoftonline.com/<TENANT_ID>/v2.0; wenn der dekodierte ver-Claim 1.0 ist, siehe Wenn deine Tokens v1.0 sind.iat und exp. Wenn der Issuer noch die 7500 des Assistenten (oder den 1-Stunden-Standard) hat, erhöhe max_jwt_lifetime_seconds auf 86400, wie in Konfiguriere Anthropic beschrieben.audience der Regel muss exakt dem aud des Tokens entsprechen: die Client-ID der Audience-App-Registrierung für die v2.0-Tokens, die dieser Leitfaden konfiguriert.appid, nicht in azp; siehe Wenn deine Tokens v1.0 sind.Verwende diesen Pfad, wenn dein Workload in einem AKS-Pod läuft. Entra Workload Identity föderiert ein Kubernetes-Service-Konto mit einer benutzerseitig zugewiesenen Managed Identity: Kubernetes projiziert ein Service-Konto-Token (signiert vom OIDC-Issuer des AKS-Clusters) in den Pod unter dem Pfad in AZURE_FEDERATED_TOKEN_FILE. Dieses projizierte Token ist kein von Entra ausgestelltes Token. Um also auf dem auf dieser Seite beschriebenen Entra-vermittelten Pfad zu bleiben, führt der Workload einen zweistufigen Austausch durch: Er löst zuerst das projizierte Token unter https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token (föderierter client_credentials-Grant) gegen ein von Entra ausgestelltes Zugriffstoken ein und übergibt dann dieses Entra-Token als Identity-Token an das Anthropic SDK.
AKS-Pods können alternativ den Entra-Austausch überspringen und das von Kubernetes projizierte Service-Konto-Token direkt bei Anthropic vorlegen. Dieser Pfad registriert den OIDC-Issuer deines AKS-Clusters bei Anthropic anstelle deines Entra-Tenants. Siehe WIF mit Kubernetes verwenden für diesen Ablauf.
Den OIDC-Issuer und Workload Identity auf deinem Cluster aktivieren
Das Aktivieren von Workload Identity installiert den azure-workload-identity Mutating Webhook für dich; installiere ihn nur auf Nicht-AKS-Clustern manuell. Erfasse die OIDC-Issuer-URL des Clusters für die föderierte Anmeldeinformation, die du in einem späteren Schritt erstellst.
az aks update \
--resource-group <RESOURCE_GROUP> \
--name <CLUSTER_NAME> \
--enable-oidc-issuer \
--enable-workload-identity
AKS_OIDC_ISSUER=$(az aks show \
--resource-group <RESOURCE_GROUP> \
--name <CLUSTER_NAME> \
--query oidcIssuerProfile.issuerUrl -o tsv)Eine benutzerseitig zugewiesene Managed Identity erstellen
Erfasse zwei Werte von der Identität: Die Client ID kommt in die Service-Konto-Annotation (und wird als AZURE_CLIENT_ID in den Pod injiziert), und die Object (principal) ID erscheint als oid-Claim, auf den deine Anthropic-Föderationsregel matcht.
az identity create \
--resource-group <RESOURCE_GROUP> \
--name claude-inference-identity \
--location <LOCATION>
# Gehört in die Service-Account-Annotation; wird als AZURE_CLIENT_ID in den Pod injiziert.
IDENTITY_CLIENT_ID=$(az identity show \
--resource-group <RESOURCE_GROUP> \
--name claude-inference-identity \
--query clientId -o tsv)
# Erscheint als oid-Claim, auf den deine Föderationsregel passt.
IDENTITY_OBJECT_ID=$(az identity show \
--resource-group <RESOURCE_GROUP> \
--name claude-inference-identity \
--query principalId -o tsv)Das annotierte Kubernetes-Service-Konto erstellen
Der azure-workload-identity-Webhook liest die Annotation azure.workload.identity/client-id, um AZURE_CLIENT_ID in den Pod zu injizieren, was die Beispiele in Token beziehen und verwenden aus der Umgebung lesen.
apiVersion: v1
kind: ServiceAccount
metadata:
name: claude-inference
namespace: inference
annotations:
azure.workload.identity/client-id: <IDENTITY_CLIENT_ID>Die föderierte Anmeldeinformation auf der Managed Identity erstellen
Die föderierte Anmeldeinformation vertraut dem OIDC-Issuer deines Clusters für dieses spezifische Service-Konto. Der Wert --audience api://AzureADTokenExchange ist Entras feste Audience für eingehende Kubernetes-Service-Konto-Tokens; er hat nichts mit der Claude API-Audience zu tun, die du zuvor registriert hast.
az identity federated-credential create \
--resource-group <RESOURCE_GROUP> \
--identity-name claude-inference-identity \
--name claude-inference-aks \
--issuer "$AKS_OIDC_ISSUER" \
--subject system:serviceaccount:inference:claude-inference \
--audience api://AzureADTokenExchangeDen Pod labeln und sein Service-Konto festlegen
Der Pod muss das Label azure.workload.identity/use: "true" tragen und als das annotierte Service-Konto laufen. Der Webhook injiziert dann AZURE_FEDERATED_TOKEN_FILE, AZURE_CLIENT_ID und AZURE_TENANT_ID in den Pod. Die Datei unter AZURE_FEDERATED_TOKEN_FILE enthält das von Kubernetes projizierte Service-Konto-Token, signiert vom OIDC-Issuer des AKS-Clusters.
apiVersion: v1
kind: Pod
metadata:
name: inference-worker
namespace: inference
labels:
azure.workload.identity/use: "true"
spec:
serviceAccountName: claude-inference
containers:
- name: app
image: your-registry/inference-worker:latestEin Beispiel-Token dekodieren
Das Token, das deine Anthropic-Föderationsregel sieht, ist nicht die projizierte Datei; es ist das von Entra ausgestellte Token, das der client_credentials-Austausch zurückgibt. Führe aus einem gelabelten Pod heraus Schritt 1 des cURL-Beispiels in Token beziehen und verwenden aus und dekodiere das Ergebnis. Es trägt dieselbe Claim-Struktur wie der Managed-Identity-Pfad:
{
"iss": "https://login.microsoftonline.com/<TENANT_ID>/v2.0",
"sub": "9f8e7d6c-1a2b-3c4d-5e6f-...",
"aud": "<APP_ID>",
"oid": "9f8e7d6c-1a2b-3c4d-5e6f-...",
"tid": "<TENANT_ID>",
"azp": "<IDENTITY_CLIENT_ID>",
"ver": "2.0",
"exp": 1775527120
}sub und oid sind die Objekt-ID der Managed Identity, aud ist die Client-ID der Audience-App-Registrierung, und azp ist die Client-ID der Managed Identity (der Wert von AZURE_CLIENT_ID). Die Lebensdauer unterscheidet sich vom Managed-Identity-Pfad: client_credentials-Tokens haben standardmäßig ein zufälliges Zeitfenster von 60 bis 90 Minuten zwischen iat und exp, nicht 24 Stunden.
Öffne in der Claude Console Settings → Workload identity, klicke auf Connect workload und wähle die Kachel Microsoft Entra. Der Assistent führt dich durch die Registrierung des Issuers, die Erstellung eines Service-Kontos und die Erstellung einer Föderationsregel.
Der Assistent erstellt diese Ressourcen für dich. Verwende die folgenden Werte, unabhängig davon, ob du sie im Assistenten eingibst oder an die Admin API sendest:
Föderations-Issuer: Wähle v2.0 (login.microsoftonline.com) im Token issuer-Selektor des Assistenten. (Der Selektor steht standardmäßig auf v1; dieser Standard existiert für Tenants, die ältere Registrierungen wiederverwenden, die noch v1.0-Tokens ausgeben.) Entra veröffentlicht ein OIDC-Discovery-Dokument unter der tenant-spezifischen Issuer-URL, verwende also den Discovery-Modus. Jeder Microsoft Entra-Tenant, den du föderierst, benötigt einen eigenen Issuer-Eintrag.
{
"name": "azure-prod-tenant",
"issuer_url": "https://login.microsoftonline.com/<TENANT_ID>/v2.0",
"jwks": { "type": "discovery" },
"max_jwt_lifetime_seconds": 7500
}Die Microsoft Entra-Kachel des Connect-workload-Assistenten erstellt den Issuer mit max_jwt_lifetime_seconds auf 7500 gesetzt (etwas über 2 Stunden), was die standardmäßige Lebensdauer von 60 bis 90 Minuten von client_credentials-Tokens abdeckt. Eine Tenant-Token-Lebensdauer-Richtlinie oder Continuous Access Evaluation (CAE) kann diese Lebensdauer verlängern. Wenn exp minus iat deines dekodierten Tokens 7500 Sekunden überschreitet, bearbeite den Issuer in Settings → Workload identity → Issuers und erhöhe max_jwt_lifetime_seconds entsprechend, sonst schlagen Austausche mit invalid_grant fehl. Wenn dein Tenant auch Managed-Identity-Workloads aus Eine Managed Identity verwenden betreibt, verwende den 86400-Wert aus diesem Abschnitt, der beide Pfade abdeckt.
Eine längere akzeptierte Lebensdauer bedeutet, dass ein geleaktes Entra-Token länger eintauschbar bleibt. Wenn ein Token leakt, ist der Hebel das Deaktivieren der Föderationsregel; ein enger oid-Match begrenzt von vornherein, welche Identitäten ein Token eintauschen können, wie in Begrenze den Geltungsbereich deiner Regel beschrieben.
Föderationsregel: Matche auf die Objekt-ID der Managed Identity und deine Tenant-ID. Für die v2.0-Tokens, die dieser Leitfaden konfiguriert, ist der audience-Wert die Client-ID der Audience-App-Registrierung (die <APP_ID>-GUID aus Registriere die Token-Audience). Verwende den exakten aud-Wert aus deinem dekodierten Token.
{
"name": "azure-inference-worker",
"issuer_id": "fdis_...",
"match": {
"audience": "<APP_ID>",
"claims": {
"oid": "9f8e7d6c-1a2b-3c4d-5e6f-...",
"tid": "<TENANT_ID>"
}
},
"target": {
"type": "service_account",
"service_account_id": "svac_..."
},
"workspace_id": "wrkspc_...",
"oauth_scope": "workspace:developer",
"token_lifetime_seconds": 600
}token_lifetime_seconds ist die Lebensdauer des Anthropic-Zugriffstokens, das der Austausch zurückgibt, nicht die des Entra-Tokens; das SDK aktualisiert es für dich.
Zur Laufzeit führt der Pod den zweistufigen Austausch durch: Er sendet das von Kubernetes projizierte Token (die Datei unter AZURE_FEDERATED_TOKEN_FILE) als föderierte client_credentials-Assertion an Entras Token-Endpunkt und tauscht dann das resultierende Entra-Zugriffstoken unter POST /v1/oauth/token ein. Jedes Anthropic SDK übernimmt den zweiten Austausch und die Aktualisierungsschleife, wenn du den Entra-Abruf als Token-Provider-Callable bereitstellst, wie in den folgenden Beispielen gezeigt. Der cURL-Tab zeigt den rohen Ablauf.
In den Beispielen erscheinen zwei verschiedene Client-IDs. <APP_ID> ist die Client-ID der Audience-App-Registrierung aus Registriere die Token-Audience; der Scope api://<APP_ID>/.default fordert von Entra ein Token an, das an diese Audience adressiert ist. $AZURE_CLIENT_ID ist die Client-ID der Managed Identity, vom Webhook injiziert, und identifiziert den Aufrufer. Verwechsle die beiden nicht.
Wenn dein Workload bereits die Azure Identity-Clientbibliothek verwendet, übergib deren Token-Beschaffung (DefaultAzureCredential mit dem Scope api://<APP_ID>/.default) als Identity-Token-Provider, anstatt den zweistufigen Austausch selbst durchzuführen. Die Bibliothek liest dieselben Umgebungsvariablen AZURE_FEDERATED_TOKEN_FILE, AZURE_CLIENT_ID und AZURE_TENANT_ID und übernimmt den Entra-Austausch.
import os
from pathlib import Path
import anthropic
import requests
from anthropic import WorkloadIdentityCredentials
def fetch_entra_token_via_federation() -> str:
federated_token = Path(os.environ["AZURE_FEDERATED_TOKEN_FILE"]).read_text()
response = requests.post(
f"https://login.microsoftonline.com/{os.environ['AZURE_TENANT_ID']}/oauth2/v2.0/token",
data={
"client_id": os.environ["AZURE_CLIENT_ID"],
"grant_type": "client_credentials",
"scope": "api://<APP_ID>/.default",
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion": federated_token,
},
timeout=5,
)
response.raise_for_status()
return response.json()["access_token"]
client = anthropic.Anthropic(
credentials=WorkloadIdentityCredentials(
identity_token_provider=fetch_entra_token_via_federation,
federation_rule_id=os.environ["ANTHROPIC_FEDERATION_RULE_ID"],
organization_id=os.environ["ANTHROPIC_ORGANIZATION_ID"],
service_account_id=os.environ["ANTHROPIC_SERVICE_ACCOUNT_ID"],
workspace_id=os.environ.get("ANTHROPIC_WORKSPACE_ID"),
),
)
message = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello from Azure"}],
)
print(next(block.text for block in message.content if block.type == "text"))Führe aus einem gelabelten Pod heraus den in Token beziehen und verwenden gezeigten cURL-Austausch aus und bestätige, dass POST /v1/oauth/token eine 200 mit einem access_token, das mit sk-ant-oat01- beginnt, und einem expires_in-Wert in Sekunden zurückgibt. Bei 400 invalid_grant dekodiere das von Entra ausgestellte Token aus Schritt 1 (siehe Einen fehlgeschlagenen Austausch beheben für den Befehl) und prüfe die häufigsten Azure-seitigen Ursachen:
issuer_url muss exakt mit dem iss-Claim des Tokens übereinstimmen. Ein v2.0-Token trägt https://login.microsoftonline.com/<TENANT_ID>/v2.0; wenn der dekodierte ver-Claim 1.0 ist, siehe Wenn deine Tokens v1.0 sind.client_credentials-Token über 7500 Sekunden hinaus verlängert, erhöhe max_jwt_lifetime_seconds des Issuers, wie in Konfiguriere Anthropic beschrieben.audience der Regel muss exakt dem aud des Tokens entsprechen: die Client-ID der Audience-App-Registrierung für die v2.0-Tokens, die dieser Leitfaden konfiguriert.appid, nicht in azp; siehe Wenn deine Tokens v1.0 sind.Dieser Leitfaden konfiguriert die Audience-App-Registrierung mit api.requestedAccessTokenVersion: 2, sodass jedes gezeigte Token v2.0 ist. Wenn du eine bestehende Registrierung wiederverwendest, bei der requestedAccessTokenVersion nicht gesetzt ist, stellt Entra stattdessen v1.0-Tokens aus. Dekodiere ein Beispiel-Token und prüfe seinen ver-Claim; wenn er 1.0 ist, ändern sich vier Dinge:
iss-Claim ist https://sts.windows.net/<TENANT_ID>/ statt https://login.microsoftonline.com/<TENANT_ID>/v2.0. Registriere die Issuer-URL exakt so, wie sie der iss-Claim deines Tokens trägt. Die beiden URLs teilen sich dasselbe JWKS, sodass der Discovery-Modus für beide funktioniert.aud-Claim ist die Identifier-URI, die du als resource übergeben hast (zum Beispiel api://<APP_ID>), nicht die Client-ID der Registrierung. Setze die audience der Föderationsregel auf den exakten aud-Wert aus deinem dekodierten Token.appid, nicht in azp. Die beiden Claims erscheinen nie im selben Token, sodass eine Regel, die auf azp matcht, bei einem v1.0-Token nie besteht.Die Claims oid, sub und tid tragen in beiden Versionen dieselben Werte, sodass der Rest dieses Leitfadens unverändert gilt.
Eine Föderationsregel kann das Subject des Tokens zusätzlich zur (oder anstelle der) claims-Map mit subject_prefix matchen; siehe Regel-Matching-Semantik dafür, wie die Felder kombiniert werden. Entra-sub-Werte für diese Identitäten sind kanonische GUIDs fester Länge, sodass ein subject_prefix, der die vollständige 36-stellige Objekt-ID enthält, nur dieses Subject matcht; dies ist eine Eigenschaft von Entras Subject-Format, nicht von subject_prefix im Allgemeinen.
Jede Identität in deinem Tenant kann ein Token für die registrierte Audience anfordern,
daher identifizieren audience und tid allein keinen bestimmten Workload. Eine Regel, die
einen oid- (oder azp/appid-) Match weglässt oder einen Wildcard- oder
Teil-GUID-subject_prefix verwendet, autorisiert jede Managed Identity und jeden Service
Principal im Tenant.
Beschränke den match-Block der Regel auf den engsten Geltungsbereich, der zu deinem Anwendungsfall passt:
oid als exakten Wert: Setze claims.oid auf die vollständige Objekt-ID der Managed Identity. Ein subject_prefix, der auf diese vollständige Objekt-ID gesetzt ist, ist äquivalent (der Console-Assistent setzt beide); verwende niemals einen Wildcard- oder Teil-GUID-subject_prefix, der mehr Identitäten matcht, als du beabsichtigst.tid als Defense in Depth: Die Issuer-URL legt deinen Tenant bereits fest, aber das Hinzufügen von claims.tid schützt vor Konfigurationsdrift, falls der Issuer-Eintrag später bearbeitet wird.audience auf den exakten aud-Wert aus deinem dekodierten Token, damit Tokens, die für andere Anwendungen ausgestellt wurden, abgelehnt werden.Was this page helpful?