Claude Platform Docs
관리자ID 공급자

Microsoft Entra ID와 함께 WIF 사용하기

Azure 관리 ID 및 Entra Workload Identity를 Claude API와 페더레이션하여 Azure 워크로드가 정적 API 키 없이 Claude를 호출할 수 있도록 합니다.

Azure 워크로드는 Microsoft Entra ID가 발급한 "JSON Web Token"(JSON 웹 토큰), 즉 JWT를 제시한 다음 이를 수명이 짧은 Anthropic 액세스 토큰으로 교환하여 Claude API에 인증합니다. 설정은 모든 Azure 플랫폼에서 동일한 형태를 따릅니다:

  1. 토큰 대상(audience) 등록: Microsoft Entra 테넌트에 Claude API 대상을 나타내는 앱 등록을 하나 생성합니다. 테넌트의 모든 워크로드는 이 대상에 대해 Entra 토큰을 요청합니다.
  2. 플랫폼에 맞는 ID 설정: VM, VM Scale Sets, App Service, Functions, Container Apps에서는 관리 ID(managed identity)를, AKS에서는 Entra Workload Identity를 사용합니다.
  3. Anthropic 구성: 테넌트의 Entra 발급자(issuer)를 등록하고, 서비스 계정을 생성하고, 토큰의 클레임과 일치하는 페더레이션 규칙을 작성합니다.
  4. 런타임에 교환: 워크로드는 Entra가 발급한 토큰을 POST /v1/oauth/token에서 sk-ant-oat01-... Anthropic 액세스 토큰으로 교환하고 이를 사용하여 Claude를 호출합니다.

두 경로 모두에서 Anthropic에 제시하는 토큰은 테넌트별 Entra 발급자와 suboid 클레임에 담긴 관리 ID의 개체 ID를 포함합니다. 워크로드가 해당 토큰을 얻는 방법만 다릅니다. 워크로드가 실행되는 위치에 맞는 섹션을 선택하세요: VM, VM Scale Sets, App Service, Functions 또는 Container Apps의 경우 관리 ID 사용, AKS의 경우 AKS에서 Entra Workload Identity 사용을 참조하세요.

사전 요구 사항

  • WIF 개념에 대한 이해: 서비스 계정, 페더레이션 발급자, 페더레이션 규칙.
  • 관리 ID를 할당할 권한(또는 AKS에서 Entra Workload Identity를 구성할 권한)이 있는 Azure 구독.
  • Microsoft Entra 테넌트에서 앱 등록 하나와 서비스 주체(service principal)를 생성할 권한(공유 Claude API 대상). Entra는 테넌트에 존재하는 대상에 대해서만 토큰을 발급하므로, 토큰 요청이 성공하려면 토큰 대상 등록 단계가 먼저 필요합니다.
  • Microsoft Entra 테넌트 ID. Azure 포털의 Microsoft Entra ID → Overview → Tenant ID에서 찾을 수 있습니다.
  • Anthropic 조직의 Claude Console에서 서비스 계정, 페더레이션 발급자, 페더레이션 규칙을 생성할 권한.

토큰 대상 등록

Microsoft Entra ID는 요청된 대상이 테넌트에 서비스 주체가 있는 앱 등록으로 존재할 때만 토큰을 발급합니다. Claude API 대상을 나타내는 앱 등록을 하나 생성하세요. 테넌트의 모든 워크로드가 이에 대한 토큰을 요청할 수 있습니다. 이 등록이 없으면 토큰 요청은 "resource not found in tenant" 오류(관리 ID 엔드포인트에서는 AADSTS50001, Entra 토큰 엔드포인트에서는 AADSTS500011)와 함께 실패합니다.

# Claude API 대상(audience)을 나타내는 앱 등록을 생성합니다.
APP_ID=$(az ad app create --display-name claude-api-federation --query appId -o tsv)

# v2.0 액세스 토큰을 요청하고 api://<APP_ID> 식별자 URI를 설정합니다.
az ad app update --id "$APP_ID" \
  --identifier-uris "api://$APP_ID" \
  --set api.requestedAccessTokenVersion=2

# 테넌트에서 대상(audience)이 확인되도록 서비스 주체를 생성합니다.
az ad sp create --id "$APP_ID"

관리 ID 사용

워크로드가 VM, VM Scale Set, App Service, Functions 또는 Container Apps에서 실행되는 경우 이 경로를 사용하세요. 워크로드는 플랫폼의 로컬 토큰 엔드포인트에서 할당된 관리 ID에 대한 Entra 발급 JWT를 요청한 다음, 해당 JWT를 Anthropic과 교환합니다.

관리 ID 구성

  1. 관리 ID 연결

    Azure 리소스에서 시스템 할당 또는 사용자 할당 관리 ID를 활성화하세요. Azure 포털에서 리소스를 열고 Identity로 이동한 다음 System assigned를 켜세요(또는 사용자 할당 ID를 연결하세요).

    ID가 생성된 후 Object (principal) ID를 기록해 두세요. 이 GUID는 발급된 토큰에서 suboid 클레임 모두에 나타나며, Anthropic 페더레이션 규칙이 이 값과 일치하는지 확인합니다. 리소스의 Identity 페이지에서 찾을 수 있으며, 사용자 할당 ID의 경우 관리 ID 리소스의 Overview 페이지에 있는 Object (principal) ID입니다. (관리 ID는 Microsoft Entra ID에 앱 등록이 아닌 서비스 주체만 가집니다.)

  2. 플랫폼의 토큰 엔드포인트 찾기

    ID가 연결되면 플랫폼은 로컬 토큰 엔드포인트를 노출합니다:

    • VM 및 VM Scale Sets: http://169.254.169.254/metadata/identity/oauth2/token의 IMDS, 헤더 Metadata: trueapi-version=2018-02-01 사용.
    • App Service, Functions, Container Apps: IDENTITY_ENDPOINT 환경 변수의 URL, 헤더 X-IDENTITY-HEADERIDENTITY_HEADER 값으로 설정하고 api-version=2019-08-01 사용. 이 플랫폼에서는 IMDS에 접근할 수 없습니다.

    리소스에 사용자 할당 관리 ID가 둘 이상 있는 경우, 토큰 요청에 client_id=<IDENTITY_CLIENT_ID>를 추가하여 하나를 선택하세요. Azure는 항상 이를 지정할 것을 권장합니다. 지정하지 않으면 결과는 리소스에 시스템 할당 ID도 활성화되어 있는지에 따라 달라집니다. 활성화되어 있으면 요청이 조용히 해당 ID로 대체되어 페더레이션 규칙의 oid 일치에 실패하고, 활성화되어 있지 않으면 두 번째 사용자 할당 ID가 연결되는 즉시 요청이 완전히 실패합니다.

  3. 샘플 토큰 디코딩

    엔드포인트에서 토큰을 요청하고 페이로드를 디코딩하여 페더레이션 규칙이 일치해야 하는 클레임을 확인하세요. (디코딩 명령은 실패한 교환 문제 해결을 참조하세요.) 관리 ID에 대한 v2.0 토큰은 다음 클레임을 포함합니다:

    {
      "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
    }
    클레임일치시켜야 하는 경우
    oid관리 ID의 개체 ID, sub와 동일특정 관리 ID 하나를 승인하려는 경우. 이것이 기본값이며, Anthropic 구성의 규칙이 이 값과 일치합니다.
    azp호출하는 ID의 클라이언트 ID하나의 앱 등록을 공유하는 모든 워크로드를 승인하려는 경우. 관리 ID의 경우 azp는 해당 ID에 고유하므로 oid와 동등합니다.
    aud대상 앱 등록의 클라이언트 ID(토큰 대상 등록<APP_ID> GUID)항상. 규칙의 audience 필드는 토큰의 aud 값과 정확히 일치해야 합니다.
    tid테넌트 ID심층 방어를 원하는 경우. 발급자 URL이 이미 테넌트를 고정합니다.

    디코딩된 토큰의 ver 클레임이 1.0이면 클레임 이름과 값이 다릅니다. 계속하기 전에 토큰이 v1.0인 경우를 참조하세요.

Anthropic 구성

Claude Console에서 Settings → Workload identity를 열고 Connect workload를 클릭한 다음 Microsoft Entra 타일을 선택하세요. 마법사가 발급자 등록, 서비스 계정 생성, 페더레이션 규칙 생성을 안내합니다.

마법사가 이러한 리소스를 대신 생성해 줍니다. 마법사에 입력하든 Admin API로 전송하든 다음 값을 사용하세요:

페더레이션 발급자: 마법사의 Token issuer 선택기에서 **v2.0 (login.microsoftonline.com)**을 선택하세요. (선택기의 기본값은 v1이며, 이 기본값은 여전히 v1.0 토큰을 발급하는 이전 등록을 재사용하는 테넌트를 위해 존재합니다.) Entra는 테넌트별 발급자 URL에 OIDC 디스커버리 문서를 게시하므로 디스커버리 모드를 사용하세요. 페더레이션하는 각 Microsoft Entra 테넌트에는 자체 발급자 레코드가 필요합니다.

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

허용되는 수명이 길어지면 유출된 Entra 토큰이 더 오래 교환 가능한 상태로 유지됩니다. 토큰이 유출되면 대응 수단은 페더레이션 규칙을 비활성화하는 것입니다. 규칙 범위 지정에 설명된 대로 엄격한 oid 일치는 애초에 어떤 ID가 토큰을 교환할 수 있는지를 제한합니다.

페더레이션 규칙: 관리 ID의 개체 ID와 테넌트 ID를 일치시키세요. 이 가이드가 구성하는 v2.0 토큰의 경우 audience 값은 대상 앱 등록의 클라이언트 ID(토큰 대상 등록<APP_ID> GUID)입니다. 디코딩된 토큰의 정확한 aud 값을 사용하세요.

{
  "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는 Entra 토큰이 아니라 교환이 반환하는 Anthropic 액세스 토큰의 수명이며, SDK가 이를 자동으로 갱신합니다.

토큰 획득 및 사용

런타임에 워크로드는 Entra 토큰을 가져와 POST /v1/oauth/token에서 교환하고, 반환된 베어러 토큰을 사용하여 Claude를 호출합니다. 다음 예제와 같이 토큰 제공자 callable을 제공하면 각 Anthropic SDK가 교환 및 갱신 루프를 처리합니다. cURL 탭은 원시 흐름을 보여줍니다.

샘플은 플랫폼의 토큰 엔드포인트에서 관리 ID 토큰을 가져옵니다. VM 및 VM Scale Sets에서는 IMDS, App Service, Functions, Container Apps에서는 IDENTITY_ENDPOINT 서비스입니다. api://<APP_ID> 리소스 값의 <APP_ID>토큰 대상 등록의 대상 앱 등록 클라이언트 ID로 바꾸세요.

import os

import anthropic
import requests
from anthropic import WorkloadIdentityCredentials

# 대상(audience) 앱 등록의 식별자 URI입니다(토큰 대상 등록 참조).
AUDIENCE = "api://<APP_ID>"


def fetch_entra_token() -> str:
    """Fetch a managed identity token from the platform's token endpoint."""
    # 사용자 할당 ID가 여러 개인 경우 client_id=<IDENTITY_CLIENT_ID>를
    # 요청 매개변수에 추가하여 하나를 선택하세요.
    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 또는 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"))

설정 확인

Azure 리소스에서 토큰 획득 및 사용에 표시된 cURL 교환을 실행하고 POST /v1/oauth/tokensk-ant-oat01-로 시작하는 access_token과 초 단위의 expires_in 값을 포함한 200을 반환하는지 확인하세요. 교환이 불투명한 401 authentication_error 응답(메시지 Authentication failed)과 함께 실패하면, 인증 기록 페이지에서 거부 사유를 확인한 다음 Entra 토큰을 디코딩하고(명령은 실패한 교환 문제 해결 참조) 가장 흔한 Azure 측 원인을 확인하세요:

  • 발급자 불일치: 등록된 issuer_url은 토큰의 iss 클레임과 정확히 일치해야 합니다. v2.0 토큰은 https://login.microsoftonline.com/<TENANT_ID>/v2.0을 포함합니다. 디코딩된 ver 클레임이 1.0이면 토큰이 v1.0인 경우를 참조하세요.
  • 토큰 수명: 관리 ID 토큰은 iatexp 사이가 최대 24시간입니다. 발급자가 여전히 마법사의 7500(또는 1시간 기본값)을 사용하는 경우 Anthropic 구성에 설명된 대로 max_jwt_lifetime_seconds86400으로 올리세요.
  • 대상 불일치: 규칙의 audience는 토큰의 aud와 정확히 일치해야 합니다. 이 가이드가 구성하는 v2.0 토큰의 경우 대상 앱 등록의 클라이언트 ID입니다.
  • 클레임 이름 불일치: 토큰에 없는 클레임과 일치시키는 규칙은 절대 통과하지 않습니다. v1.0 토큰은 클라이언트 ID를 azp가 아닌 appid에 담습니다. 토큰이 v1.0인 경우를 참조하세요.

AKS에서 Entra Workload Identity 사용

워크로드가 AKS 파드에서 실행되는 경우 이 경로를 사용하세요. Entra Workload Identity는 Kubernetes 서비스 계정을 사용자 할당 관리 ID와 페더레이션합니다. Kubernetes는 서비스 계정 토큰(AKS 클러스터의 OIDC 발급자가 서명)을 AZURE_FEDERATED_TOKEN_FILE의 경로로 파드에 프로젝션합니다. 이 프로젝션된 토큰은 Entra가 발급한 토큰이 아니므로, 이 페이지에서 설명하는 Entra 매개 경로를 유지하기 위해 워크로드는 2단계 교환을 수행합니다. 먼저 프로젝션된 토큰을 https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token(페더레이션된 client_credentials 그랜트)에서 Entra 발급 액세스 토큰으로 교환한 다음, 해당 Entra 토큰을 ID 토큰으로 Anthropic SDK에 전달합니다.

Entra Workload Identity 구성

  1. 클러스터에서 OIDC 발급자 및 워크로드 ID 활성화

    워크로드 ID를 활성화하면 azure-workload-identity 변형(mutating) 웹훅이 자동으로 설치됩니다. AKS가 아닌 클러스터에서만 수동으로 배포하세요. 이후 단계에서 생성할 페더레이션 자격 증명을 위해 클러스터의 OIDC 발급자 URL을 기록해 두세요.

    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)
  2. 사용자 할당 관리 ID 생성

    ID에서 두 가지 값을 기록하세요. Client ID는 서비스 계정 어노테이션에 들어가며(파드에 AZURE_CLIENT_ID로 주입됨), Object (principal) ID는 Anthropic 페더레이션 규칙이 일치시키는 oid 클레임으로 나타납니다.

    az identity create \
      --resource-group <RESOURCE_GROUP> \
      --name claude-inference-identity \
      --location <LOCATION>
    
    # 서비스 계정 어노테이션에 들어가며, 파드에 AZURE_CLIENT_ID로 주입됩니다.
    IDENTITY_CLIENT_ID=$(az identity show \
      --resource-group <RESOURCE_GROUP> \
      --name claude-inference-identity \
      --query clientId -o tsv)
    
    # 페더레이션 규칙이 매칭하는 oid 클레임으로 나타납니다.
    IDENTITY_OBJECT_ID=$(az identity show \
      --resource-group <RESOURCE_GROUP> \
      --name claude-inference-identity \
      --query principalId -o tsv)
  3. 어노테이션이 지정된 Kubernetes 서비스 계정 생성

    azure-workload-identity 웹훅은 azure.workload.identity/client-id 어노테이션을 읽어 파드에 AZURE_CLIENT_ID를 주입하며, 토큰 획득 및 사용의 샘플은 이를 환경에서 읽습니다.

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: claude-inference
      namespace: inference
      annotations:
        azure.workload.identity/client-id: <IDENTITY_CLIENT_ID>
  4. 관리 ID에 페더레이션 자격 증명 생성

    페더레이션 자격 증명은 해당 특정 서비스 계정에 대해 클러스터의 OIDC 발급자를 신뢰합니다. --audience api://AzureADTokenExchange 값은 들어오는 Kubernetes 서비스 계정 토큰에 대한 Entra의 고정 대상이며, 앞서 등록한 Claude API 대상과는 무관합니다.

    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://AzureADTokenExchange
  5. 파드에 레이블을 지정하고 서비스 계정 설정

    파드는 azure.workload.identity/use: "true" 레이블을 가져야 하며 어노테이션이 지정된 서비스 계정으로 실행되어야 합니다. 그러면 웹훅이 AZURE_FEDERATED_TOKEN_FILE, AZURE_CLIENT_ID, AZURE_TENANT_ID를 파드에 주입합니다. AZURE_FEDERATED_TOKEN_FILE의 파일에는 AKS 클러스터의 OIDC 발급자가 서명한 Kubernetes 프로젝션 서비스 계정 토큰이 들어 있습니다.

    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:latest
  6. 샘플 토큰 디코딩

    Anthropic 페더레이션 규칙이 보는 토큰은 프로젝션된 파일이 아니라 client_credentials 교환이 반환하는 Entra 발급 토큰입니다. 레이블이 지정된 파드 내부에서 토큰 획득 및 사용의 cURL 샘플 1단계를 실행하고 결과를 디코딩하세요. 관리 ID 경로와 동일한 클레임 형태를 가집니다:

    {
      "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
    }

    suboid는 관리 ID의 개체 ID이고, aud는 대상 앱 등록의 클라이언트 ID이며, azp는 관리 ID의 클라이언트 ID(AZURE_CLIENT_ID의 값)입니다. 수명은 관리 ID 경로와 다릅니다. client_credentials 토큰은 기본적으로 iatexp 사이가 24시간이 아닌 60~90분의 무작위 기간입니다.

Anthropic 구성

Claude Console에서 Settings → Workload identity를 열고 Connect workload를 클릭한 다음 Microsoft Entra 타일을 선택하세요. 마법사가 발급자 등록, 서비스 계정 생성, 페더레이션 규칙 생성을 안내합니다.

마법사가 이러한 리소스를 대신 생성해 줍니다. 마법사에 입력하든 Admin API로 전송하든 다음 값을 사용하세요:

페더레이션 발급자: 마법사의 Token issuer 선택기에서 **v2.0 (login.microsoftonline.com)**을 선택하세요. (선택기의 기본값은 v1이며, 이 기본값은 여전히 v1.0 토큰을 발급하는 이전 등록을 재사용하는 테넌트를 위해 존재합니다.) Entra는 테넌트별 발급자 URL에 OIDC 디스커버리 문서를 게시하므로 디스커버리 모드를 사용하세요. 페더레이션하는 각 Microsoft Entra 테넌트에는 자체 발급자 레코드가 필요합니다.

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

허용되는 수명이 길어지면 유출된 Entra 토큰이 더 오래 교환 가능한 상태로 유지됩니다. 토큰이 유출되면 대응 수단은 페더레이션 규칙을 비활성화하는 것입니다. 규칙 범위 지정에 설명된 대로 엄격한 oid 일치는 애초에 어떤 ID가 토큰을 교환할 수 있는지를 제한합니다.

페더레이션 규칙: 관리 ID의 개체 ID와 테넌트 ID를 일치시키세요. 이 가이드가 구성하는 v2.0 토큰의 경우 audience 값은 대상 앱 등록의 클라이언트 ID(토큰 대상 등록<APP_ID> GUID)입니다. 디코딩된 토큰의 정확한 aud 값을 사용하세요.

{
  "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는 Entra 토큰이 아니라 교환이 반환하는 Anthropic 액세스 토큰의 수명이며, SDK가 이를 자동으로 갱신합니다.

토큰 획득 및 사용

런타임에 파드는 2단계 교환을 수행합니다. Kubernetes가 프로젝션한 토큰(AZURE_FEDERATED_TOKEN_FILE의 파일)을 페더레이션된 client_credentials 어설션으로 Entra의 토큰 엔드포인트에 보낸 다음, 결과로 받은 Entra 액세스 토큰을 POST /v1/oauth/token에서 교환합니다. 다음 예제와 같이 Entra 가져오기를 토큰 제공자 callable로 제공하면 각 Anthropic SDK가 두 번째 교환과 갱신 루프를 처리합니다. cURL 탭은 원시 흐름을 보여줍니다.

샘플에는 서로 다른 두 개의 클라이언트 ID가 나타납니다. <APP_ID>토큰 대상 등록의 대상 앱 등록 클라이언트 ID이며, 스코프 api://<APP_ID>/.default는 Entra에 해당 대상을 수신자로 하는 토큰을 요청합니다. $AZURE_CLIENT_ID는 웹훅이 주입한 관리 ID의 클라이언트 ID이며 호출자를 식별합니다. 둘을 서로 바꿔 사용하지 마세요.

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

설정 확인

레이블이 지정된 파드 내부에서 토큰 획득 및 사용에 표시된 cURL 교환을 실행하고 POST /v1/oauth/tokensk-ant-oat01-로 시작하는 access_token과 초 단위의 expires_in 값을 포함한 200을 반환하는지 확인하세요. 교환이 불투명한 401 authentication_error 응답(메시지 Authentication failed)과 함께 실패하면, 인증 기록 페이지에서 거부 사유를 확인한 다음 1단계의 Entra 발급 토큰을 디코딩하고(명령은 실패한 교환 문제 해결 참조) 가장 흔한 Azure 측 원인을 확인하세요:

  • 발급자 불일치: 등록된 issuer_url은 토큰의 iss 클레임과 정확히 일치해야 합니다. v2.0 토큰은 https://login.microsoftonline.com/<TENANT_ID>/v2.0을 포함합니다. 디코딩된 ver 클레임이 1.0이면 토큰이 v1.0인 경우를 참조하세요.
  • 토큰 수명: 테넌트 토큰 수명 정책 또는 CAE가 client_credentials 토큰을 7500초 이상으로 연장하는 경우, Anthropic 구성에 설명된 대로 발급자의 max_jwt_lifetime_seconds를 올리세요.
  • 대상 불일치: 규칙의 audience는 토큰의 aud와 정확히 일치해야 합니다. 이 가이드가 구성하는 v2.0 토큰의 경우 대상 앱 등록의 클라이언트 ID입니다.
  • 클레임 이름 불일치: 토큰에 없는 클레임과 일치시키는 규칙은 절대 통과하지 않습니다. v1.0 토큰은 클라이언트 ID를 azp가 아닌 appid에 담습니다. 토큰이 v1.0인 경우를 참조하세요.

토큰이 v1.0인 경우

이 가이드는 대상 앱 등록을 api.requestedAccessTokenVersion: 2로 구성하므로 표시되는 모든 토큰은 v2.0입니다. requestedAccessTokenVersion을 설정하지 않은 기존 등록을 재사용하면 Entra는 대신 v1.0 토큰을 발급합니다. 샘플 토큰을 디코딩하고 ver 클레임을 확인하세요. 1.0이면 네 가지가 달라집니다:

  • 발급자: iss 클레임은 https://login.microsoftonline.com/<TENANT_ID>/v2.0 대신 https://sts.windows.net/<TENANT_ID>/입니다. 토큰의 iss 클레임에 담긴 그대로 발급자 URL을 등록하세요. 두 URL은 동일한 JWKS를 공유하므로 디스커버리 모드는 어느 쪽에서든 작동합니다.
  • 마법사 선택기: Connect workload 마법사의 Token issuer 선택기에서 v2.0 (login.microsoftonline.com) 대신 **v1 (sts.windows.net)**을 선택하세요.
  • 대상: aud 클레임은 등록의 클라이언트 ID가 아니라 resource로 전달한 식별자 URI(예: api://<APP_ID>)입니다. 페더레이션 규칙의 audience를 디코딩된 토큰의 정확한 aud 값으로 설정하세요.
  • 클라이언트 ID 클레임: 호출하는 ID의 클라이언트 ID는 azp가 아닌 appid에 나타납니다. 두 클레임은 같은 토큰에 함께 나타나지 않으므로, azp와 일치시키는 규칙은 v1.0 토큰에 대해 절대 통과하지 않습니다.

oid, sub, tid 클레임은 두 버전에서 동일한 값을 가지므로 이 가이드의 나머지 부분은 변경 없이 적용됩니다.

규칙 범위 지정

페더레이션 규칙은 claims 맵에 추가로(또는 대신) subject_prefix로 토큰의 주체(subject)를 일치시킬 수 있습니다. 필드가 결합되는 방식은 규칙 일치 의미론을 참조하세요. 이러한 ID에 대한 Entra sub 값은 고정 길이의 정규 GUID이므로, 전체 36자 개체 ID를 포함하는 subject_prefix는 해당 주체와만 일치합니다. 이는 일반적인 subject_prefix의 속성이 아니라 Entra 주체 형식의 속성입니다.

규칙의 match 블록을 사용 사례에 맞는 가장 좁은 범위로 고정하세요:

  • oid를 정확한 값으로 일치: claims.oid를 관리 ID의 전체 개체 ID로 설정하세요. 해당 전체 개체 ID로 설정된 subject_prefix는 동등합니다(Console 마법사는 둘 다 설정합니다). 의도한 것보다 더 많은 ID와 일치하는 와일드카드 또는 부분 GUID subject_prefix는 절대 사용하지 마세요.
  • 심층 방어로 tid 고정: 발급자 URL이 이미 테넌트를 고정하지만, claims.tid를 추가하면 나중에 발급자 레코드가 편집될 경우의 구성 드리프트를 방지합니다.
  • 대상 고정: 다른 애플리케이션용으로 발급된 토큰이 거부되도록 audience를 디코딩된 토큰의 정확한 aud 값으로 설정하세요.
  • 관리 ID마다 별도의 규칙 사용: 여러 ID를 승인하는 하나의 규칙 대신 각 ID마다 하나의 규칙을 생성하여, 다른 워크로드에 영향을 주지 않고 단일 워크로드의 액세스를 취소할 수 있도록 하세요.

다음 단계

Was this page helpful?