Loading...
    • Messages
    • Managed Agents
    • Admin
    Search...
    ⌘K
    Organization
    Admin API overviewWorkspaces
    Authentication
    OverviewWorkload Identity FederationWIF reference
    AWSGoogle CloudMicrosoft AzureGitHub ActionsKubernetesOkta
    Monitoring
    Usage and Cost APIRate Limits APIClaude Code Analytics API
    Data & compliance
    Data residencyAPI and data retention
    Log in
    Microsoft Azure
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...

    Solutions

    • AI agents
    • Code modernization
    • Coding
    • Customer support
    • Education
    • Financial services
    • Government
    • Life sciences

    Partners

    • Amazon Bedrock
    • Google Cloud's Vertex AI

    Learn

    • Blog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Company

    • Anthropic
    • Careers
    • Economic Futures
    • Research
    • News
    • Responsible Scaling Policy
    • Security and compliance
    • Transparency

    Learn

    • Blog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Help and security

    • Availability
    • Status
    • Support
    • Discord

    Terms and policies

    • Privacy policy
    • Responsible disclosure policy
    • Terms of service: Commercial
    • Terms of service: Consumer
    • Usage policy
    Admin/Identity providers

    Use WIF with Microsoft Azure

    Federate Azure managed identities and Entra Workload Identity with the Claude API so your Azure workloads can call Claude without static API keys.

    Was this page helpful?

    • Prerequisites
    • Configure Azure
    • Token claims
    • Configure Anthropic
    • Acquire and use the token
    • On AKS with Entra Workload Identity
    • Verify the setup
    • Scope your rule
    • Next steps

    Azure workloads authenticate to the Claude API by presenting a JSON Web Token (JWT) issued by Microsoft Entra ID, then exchanging it for a short-lived Anthropic access token. There are two common ways to obtain the Entra-issued token:

    • Managed identity (VMs, App Service, Functions, Container Apps): The workload calls the Azure Instance Metadata Service (IMDS) at http://169.254.169.254/metadata/identity/oauth2/token and receives a JWT for its assigned identity.
    • Entra Workload Identity (AKS pods): Kubernetes projects a service account token (signed by the AKS cluster's OIDC issuer) into the pod at the path in AZURE_FEDERATED_TOKEN_FILE. The workload exchanges that token at Entra for an Entra-issued access token.

    In both cases the Entra-issued token you present to Anthropic has the tenant-specific issuer https://login.microsoftonline.com/<TENANT_ID>/v2.0 and carries the managed identity's object ID in the sub and oid claims. You register that issuer with Anthropic once, write a federation rule that matches the expected claims, and your workload exchanges its Entra token for an sk-ant-oat01-... access token at runtime.

    AKS pods can alternatively skip the Entra exchange and present the Kubernetes-projected service account token to Anthropic directly. That path registers your AKS cluster's OIDC issuer with Anthropic instead of your Entra tenant. See Kubernetes for that flow.

    Prerequisites

    • Familiarity with WIF concepts: service accounts, federation issuers, and federation rules.
    • An Azure subscription with permission to assign managed identities (or configure Entra Workload Identity on AKS).
    • Your Microsoft Entra tenant ID. Find it in the Azure portal under Microsoft Entra ID → Overview → Tenant ID.
    • Permission to create service accounts, federation issuers, and federation rules in the Claude Console for your Anthropic organization.

    Configure Azure

    Set up the identity that Azure will issue tokens for. Choose the path that matches where your workload runs.

    Token claims

    An Entra-issued token for a managed identity carries these claims:

    {
      "iss": "https://login.microsoftonline.com/<TENANT_ID>/v2.0",
      "sub": "9f8e7d6c-1a2b-3c4d-5e6f-...",
      "aud": "https://api.anthropic.com",
      "oid": "9f8e7d6c-1a2b-3c4d-5e6f-...",
      "tid": "<TENANT_ID>",
      "azp": "<CLIENT_ID>",
      "exp": 1775527120
    }

    sub and oid are identical (the managed identity's object ID). azp is the application or client ID. Match on oid to authorize one specific identity, or on azp to authorize any identity associated with an application registration. The tid claim repeats your tenant ID; matching on it is defense in depth, because the issuer URL already pins the tenant.

    Configure Anthropic

    Follow the setup walkthrough to register a federation issuer, create an Anthropic service account, and create a federation rule in the Claude Console. In the Console, choose the OIDC provider option and supply the Entra-specific values that follow.

    Federation issuer: Entra publishes an OIDC discovery document at the per-tenant issuer URL, so use discovery mode. Each Azure tenant you federate needs its own issuer record.

    {
      "name": "azure-prod-tenant",
      "issuer_url": "https://login.microsoftonline.com/<TENANT_ID>/v2.0",
      "jwks_source": "discovery"
    }

    Depending on the token version, the iss claim may be https://sts.windows.net/<TENANT_ID>/ instead. Decode your managed-identity token (the Verify section below shows how) and register whichever iss value it contains. The two URLs share the same JWKS, so discovery mode works for either.

    Federation rule: Match on the managed identity's object ID and your tenant ID.

    {
      "name": "azure-inference-worker",
      "issuer_id": "fdis_...",
      "match": {
        "audience": "https://api.anthropic.com",
        "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
    }

    Acquire and use the token

    At runtime your workload fetches its Entra token, exchanges it at POST /v1/oauth/token, and uses the returned bearer token to call Claude. Each Anthropic SDK handles the exchange and refresh loop when you supply a token-provider callable, as shown in the following examples. The cURL tab shows the raw flow.

    On AKS with Entra Workload Identity

    On AKS, the file at AZURE_FEDERATED_TOKEN_FILE is a Kubernetes-projected service account token signed by your cluster's OIDC issuer, not an Entra-issued token. To stay on the Entra-mediated path described on this page, exchange that token at https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token (federated client_credentials grant) first, then pass the resulting Entra access token to the Anthropic SDK as the identity token.

    Alternatively, register your AKS cluster's OIDC issuer with Anthropic directly and skip the Entra hop. See Kubernetes for that pattern.

    Verify the setup

    From your Azure resource, run the cURL exchange shown earlier and confirm that POST /v1/oauth/token returns a 200 with an access_token beginning with sk-ant-oat01- and an expires_in value in seconds. On 400 invalid_grant, see Troubleshoot a failed exchange; the most common Azure-side cause is a mismatch between the issuer_url you registered and the iss claim in your decoded token. They must match exactly. For managed-identity tokens the iss value is either https://login.microsoftonline.com/<TENANT_ID>/v2.0 or https://sts.windows.net/<TENANT_ID>/.

    Scope your rule

    The oid claim is a managed identity's GUID and has no stable prefix. A subject_prefix with * matches arbitrary identities in the tenant, so any workload that holds a managed identity could obtain a federated Anthropic token.

    Lock the rule's match block to the narrowest scope that fits your use case:

    • Match oid as an exact value: Set claims.oid to the managed identity's full object ID and never use subject_prefix for Azure tokens.
    • Pin tid as defense in depth: The issuer URL already pins your tenant, but adding claims.tid guards against configuration drift if the issuer record is later edited.
    • Pin the audience: Set audience to https://api.anthropic.com so tokens minted for other resources are rejected.
    • Use a separate rule per managed identity: Create one rule per identity rather than one rule that authorizes several, so you can revoke a single workload's access without affecting others.

    Next steps

    • Review the full configuration model in Workload Identity Federation.
    • See the provider guides for AWS, Google Cloud, GitHub Actions, and Kubernetes.
    • For environment variables, profile files, and credential precedence, see the WIF reference.
    import os
    
    import anthropic
    import requests
    from anthropic import WorkloadIdentityCredentials
    
    IMDS_URL = "http://169.254.169.254/metadata/identity/oauth2/token"
    
    
    def fetch_entra_token() -> str:
        """Fetch a managed identity token from Azure IMDS."""
        response = requests.get(
            IMDS_URL,
            headers={"Metadata": "true"},
            params={"api-version": "2018-02-01", "resource": "https://api.anthropic.com"},
            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"],
        ),
    )
    
    message = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        messages=[{"role": "user", "content": "Hello from Azure"}],
    )
    print(message.content[0].text)
    import os
    from pathlib import Path
    import httpx
    import anthropic
    from anthropic import WorkloadIdentityCredentials
    
    
    def fetch_entra_token_via_federation() -> str:
        federated_token = Path(os.environ["AZURE_FEDERATED_TOKEN_FILE"]).read_text()
        response = httpx.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": "https://api.anthropic.com/.default",
                "client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
                "client_assertion": federated_token,
            },
        )
        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"],
        ),
    )
    
    message = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        messages=[{"role": "user", "content": "Hello from Azure"}],
    )
    print(message.content[0].text)