Claude Platform Docs
管理身分提供者

搭配 AWS 使用 WIF

透過 Workload Identity Federation 與 STS 簽發的身分權杖,讓 Lambda、EC2、ECS 或 EKS 上的 AWS 工作負載向 Claude API 進行驗證。

AWS 工作負載可以透過交換由 AWS 簽署的 OIDC 身分權杖(identity token)向 Claude API 進行驗證,而無需使用靜態 API 金鑰。建議的路徑是呼叫 AWS STS GetWebIdentityToken API,只要工作負載擁有 AWS 憑證,此方法在任何地方都適用:Lambda、EC2、ECS 與 EKS。EKS 工作負載也可以改用 Kubernetes 投射權杖路徑,其設定步驟較少,但僅能在 pod 內運作。

本指南將說明這兩種路徑。關於底層概念(服務帳戶、聯合簽發者與聯合規則),請參閱 Workload Identity Federation

先決條件

  • 熟悉 WIF 概念:「service accounts」(服務帳戶)、「federation issuers」(聯合簽發者)與「federation rules」(聯合規則)。
  • 一個已附加 IAM 角色的 AWS 工作負載(EKS pod、ECS 任務、Lambda 函式或 EC2 執行個體)。
  • 工作負載中可使用 aws CLI 或 AWS SDK。
  • 擁有在 Claude Console 中為您的 Anthropic 組織建立服務帳戶、聯合簽發者與聯合規則的權限。

AWS STS GetWebIdentityToken API 會回傳一個由 AWS 簽署、用以聲明呼叫者 IAM 身分的 OIDC 權杖。由於它使用工作負載環境中既有的 AWS 憑證,因此同一套整合即可涵蓋 Lambda、EC2、ECS 與 EKS。

設定 AWS

  1. 為帳戶啟用對外 web identity 聯合

    這是一個帳戶層級的旗標,預設為關閉。在 AWS 主控台中,開啟 IAM,選擇 Account settings,然後啟用 Outbound web identity federation。若要以程式方式啟用:

    python3 -c "import boto3; boto3.client('iam').enable_outbound_web_identity_federation()"

    若未啟用此功能,呼叫 GetWebIdentityToken 將會失敗並回傳 OutboundWebIdentityFederationDisabledException

  2. 授予工作負載的 IAM 角色呼叫此 API 的權限

    將此政策附加到您的 Lambda 函式、EC2 執行個體或 ECS 任務所使用的 IAM 角色:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": ["sts:GetWebIdentityToken"],
          "Resource": "*"
        }
      ]
    }
  3. 找出您帳戶的 STS 簽發者 URL

    啟用對外聯合後,IAM > Account settings 頁面會顯示一個 Get Token Issuer URL 欄位,其值的格式為 https://<uuid>.tokens.sts.global.api.aws。此 URL 對您的 AWS 帳戶而言是唯一的;請複製它以供下一步使用。若要以程式方式取得:

    python3 -c "import boto3; print(boto3.client('iam').get_outbound_web_identity_federation_info())"

設定 Anthropic

在 Claude Console 中,開啟 Settings → Workload identity,點擊 Connect workload,然後選擇 AWS 圖塊。精靈會引導您完成註冊簽發者、建立服務帳戶以及建立聯合規則。

精靈會為您建立這些資源。無論您是在精靈中輸入這些值,還是將它們傳送至 Admin API,請使用下列值:

聯合簽發者: 註冊您在前一步驟中複製的每帳戶專屬 STS 簽發者 URL。它公開了一個公用的 JWKS 端點,因此請使用探索(discovery)模式。

{
  "name": "aws-sts",
  "issuer_url": "https://<uuid>.tokens.sts.global.api.aws",
  "jwks": { "type": "discovery" }
}

聯合規則: 比對您傳遞給 GetWebIdentityToken 的 audience,以及 sub 宣告中呼叫角色的 IAM 角色 ARN。sub 的值是呼叫此 API 之工作負載的 IAM 角色 ARN,格式為 arn:aws:iam::<account>:role/<role-name>。該權杖還帶有一個 https://sts.amazonaws.com/ 宣告,其中包含 aws_accountorg_idprincipal_id 以及您傳入的任何 request_tags;您可以透過規則的 claims 對應表或 CEL condition 來比對這些值,以進行更精細的控制。

{
  "name": "prod-inference",
  "issuer_id": "fdis_...",
  "match": {
    "subject_prefix": "arn:aws:iam::123456789012:role/inference-worker",
    "audience": "https://api.anthropic.com"
  },
  "target": { "type": "service_account", "service_account_id": "svac_..." },
  "workspace_id": "wrkspc_...",
  "oauth_scope": "workspace:developer",
  "token_lifetime_seconds": 600
}

請在工作負載允許的範圍內盡可能具體。比對確切的角色 ARN,且僅在多個 IAM 角色應對應到同一個 Anthropic 服務帳戶時,才放寬 subject_prefix(例如放寬為 arn:aws:iam::123456789012:role/*)。

取得並使用權杖

https://api.anthropic.com 作為 audience 呼叫 GetWebIdentityToken,然後將結果傳遞給 SDK 的聯合憑證。權杖提供者是一個可呼叫物件(callable),因此 SDK 會在每次重新整理時重新呼叫 STS。

import os

import anthropic
import boto3
from anthropic import WorkloadIdentityCredentials


def get_sts_web_identity_token() -> str:
    sts = boto3.client("sts", region_name="us-east-1")
    resp = sts.get_web_identity_token(
        Audience=["https://api.anthropic.com"],
        SigningAlgorithm="RS256",
        DurationSeconds=900,
    )
    return resp["WebIdentityToken"]


client = anthropic.Anthropic(
    credentials=WorkloadIdentityCredentials(
        identity_token_provider=get_sts_web_identity_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 AWS"}],
)
print(next(block.text for block in message.content if block.type == "text"))

驗證設定

從工作負載內部,直接交換一個由 STS 簽發的權杖並檢視回應:

cURL
JWT=$(aws sts get-web-identity-token \
  --region us-east-1 \
  --audience "https://api.anthropic.com" \
  --signing-algorithm RS256 \
  --duration-seconds 900 \
  --query WebIdentityToken --output text)

curl -sS https://api.anthropic.com/v1/oauth/token \
  -H "content-type: application/json" \
  -d "{
    \"grant_type\": \"urn:ietf:params:oauth:grant-type:jwt-bearer\",
    \"assertion\": \"$JWT\",
    \"federation_rule_id\": \"fdrl_...\",
    \"organization_id\": \"00000000-0000-0000-0000-000000000000\",
    \"service_account_id\": \"svac_...\",
    \"workspace_id\": \"wrkspc_...\"
  }" | jq

成功的交換會回傳一個以 sk-ant-oat01- 開頭的 access_token,以及一個以秒為單位的 expires_in 值。如果交換失敗並回傳不透明的 401 authentication_error 回應(訊息為 Authentication failed),請查看驗證歷史記錄頁面以了解拒絕原因,並參閱疑難排解失敗的交換;AWS 端最常見的原因是 iss 不符(每帳戶專屬的 STS 簽發者 URL 必須與已註冊的 issuer_url 完全一致)。

使用 EKS 投射的服務帳戶權杖

如果您的工作負載在 EKS pod 中執行,您可以略過 STS 呼叫,直接從磁碟讀取 Kubernetes 投射的服務帳戶權杖。Kubernetes 原生會將一個與 OIDC 相容的權杖投射到 pod 中,而 SDK 可以從檔案路徑讀取它,因此不需要權杖提供者可呼叫物件。此路徑比 STS 路徑少了兩個 AWS 設定步驟,但僅能在 pod 內運作;其底層機制與通用 Kubernetes 整合相同。

此路徑另外需要一個已啟用 IAM OIDC 提供者的 EKS 叢集,以及對該叢集的 kubectl 存取權限。

設定您的 EKS 叢集

  1. 找出您叢集的 OIDC 簽發者 URL

    每個 EKS 叢集都有一個唯一的 OIDC 簽發者。使用 AWS CLI 取得它:

    CLI
    aws eks describe-cluster \
      --name <cluster-name> \
      --query "cluster.identity.oidc.issuer" \
      --output text

    輸出看起來像 https://oidc.eks.us-west-2.amazonaws.com/id/6FA42E7BFDE8549CB...。您將在下一節中把此 URL 註冊為聯合簽發者。

  2. 建立服務帳戶並投射一個以 Anthropic 為 audience 的權杖

    EKS pod identity webhook 會偵測 eks.amazonaws.com/role-arn 註解,並自動投射一個 aud: sts.amazonaws.com 的權杖,將其路徑公開為 AWS_WEB_IDENTITY_TOKEN_FILE。該權杖用於 AWS 角色擔任(role assumption)。對於 Anthropic 交換,請投射第二個 audience: https://api.anthropic.com 的權杖,並將其掛載到專用路徑。

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: inference-worker
      namespace: inference
      annotations:
        eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/inference-worker
    apiVersion: v1
    kind: Pod
    metadata:
      name: inference-worker
      namespace: inference
    spec:
      serviceAccountName: inference-worker
      volumes:
        - name: anthropic-token
          projected:
            sources:
              - serviceAccountToken:
                  audience: https://api.anthropic.com
                  expirationSeconds: 3600
                  path: token
      containers:
        - name: app
          image: your-registry/inference-worker:latest
          env:
            - name: ANTHROPIC_IDENTITY_TOKEN_FILE
              value: /var/run/secrets/anthropic.com/token
            - name: ANTHROPIC_FEDERATION_RULE_ID
              value: fdrl_...
            - name: ANTHROPIC_ORGANIZATION_ID
              value: 00000000-0000-0000-0000-000000000000
            - name: ANTHROPIC_SERVICE_ACCOUNT_ID
              value: svac_...
            - name: ANTHROPIC_WORKSPACE_ID  # required when the rule covers multiple workspaces
              value: wrkspc_...
          volumeMounts:
            - name: anthropic-token
              mountPath: /var/run/secrets/anthropic.com
              readOnly: true
  3. 留意權杖的宣告結構

    投射的權杖是一個由您叢集的 OIDC 簽發者簽署的「JSON Web Token」(JSON 網路權杖),即 JWT。其 sub 宣告遵循 Kubernetes 慣例 system:serviceaccount:<namespace>:<service-account-name>

    {
      "iss": "https://oidc.eks.us-west-2.amazonaws.com/id/6FA42E7BFDE8549CB...",
      "sub": "system:serviceaccount:inference:inference-worker",
      "aud": ["https://api.anthropic.com"],
      "kubernetes.io": {
        "namespace": "inference",
        "serviceaccount": { "name": "inference-worker", "uid": "..." }
      },
      "exp": 1775527120,
      "iat": 1775523520
    }

    serviceAccountToken 投射會將 aud 設為 https://api.anthropic.com。位於 AWS_WEB_IDENTITY_TOKEN_FILE 的另一個由 IRSA 注入的權杖帶有 aud: sts.amazonaws.com,用於 AWS API 呼叫,而非此交換。

設定 Anthropic

在 Claude Console 中,開啟 Settings → Workload identity,點擊 Connect workload,然後選擇 AWS 圖塊。精靈會引導您完成註冊簽發者、建立服務帳戶以及建立聯合規則。

精靈會為您建立這些資源。無論您是在精靈中輸入這些值,還是將它們傳送至 Admin API,請使用下列值:

聯合簽發者: EKS 簽發者公開了一個公用的 JWKS 端點,因此請使用探索模式。簽發者 URL 必須與權杖的 iss 宣告完全一致。每個叢集註冊一個簽發者。

{
  "name": "prod-eks-uswest2",
  "issuer_url": "https://oidc.eks.us-west-2.amazonaws.com/id/6FA42E7BFDE8549CB...",
  "jwks": { "type": "discovery" }
}

聯合規則: 比對 Kubernetes 的 sub 宣告與 Anthropic audience https://api.anthropic.com。(請投射一個具有該 audience 的專用服務帳戶權杖;不要重複使用 IRSA 預設的 sts.amazonaws.com 權杖。)

{
  "name": "prod-inference",
  "issuer_id": "fdis_...",
  "match": {
    "subject_prefix": "system:serviceaccount:inference:inference-worker",
    "audience": "https://api.anthropic.com"
  },
  "target": { "type": "service_account", "service_account_id": "svac_..." },
  "workspace_id": "wrkspc_...",
  "oauth_scope": "workspace:developer",
  "token_lifetime_seconds": 600
}

請在工作負載允許的範圍內盡可能具體。僅在命名空間中的每個服務帳戶都應對應到同一個 Anthropic 服務帳戶時,才將 subject_prefix 放寬為 system:serviceaccount:inference:*(結尾的 * 使其成為前綴比對)。

取得並使用權杖

在 pod 內部,投射的權杖位於 /var/run/secrets/anthropic.com/token(在 Pod 規格中公開為 ANTHROPIC_IDENTITY_TOKEN_FILE)。將該檔案傳遞給 SDK 的聯合憑證,SDK 便會處理交換與重新整理。

import os

import anthropic
from anthropic import IdentityTokenFile, WorkloadIdentityCredentials

client = anthropic.Anthropic(
    credentials=WorkloadIdentityCredentials(
        identity_token_provider=IdentityTokenFile(
            os.environ["ANTHROPIC_IDENTITY_TOKEN_FILE"]
        ),
        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 EKS"}],
)
print(next(block.text for block in message.content if block.type == "text"))

驗證設定

從 pod 內部,直接交換投射的權杖並檢視回應:

cURL
JWT=$(cat "$ANTHROPIC_IDENTITY_TOKEN_FILE")

curl -sS https://api.anthropic.com/v1/oauth/token \
  -H "content-type: application/json" \
  -d "{
    \"grant_type\": \"urn:ietf:params:oauth:grant-type:jwt-bearer\",
    \"assertion\": \"$JWT\",
    \"federation_rule_id\": \"$ANTHROPIC_FEDERATION_RULE_ID\",
    \"organization_id\": \"$ANTHROPIC_ORGANIZATION_ID\",
    \"service_account_id\": \"$ANTHROPIC_SERVICE_ACCOUNT_ID\",
    \"workspace_id\": \"$ANTHROPIC_WORKSPACE_ID\"
  }" | jq

成功的交換會回傳一個以 sk-ant-oat01- 開頭的 access_token,以及一個以秒為單位的 expires_in 值。如果交換失敗並回傳不透明的 401 authentication_error 回應(訊息為 Authentication failed),請查看驗證歷史記錄頁面以了解拒絕原因,並參閱疑難排解失敗的交換;EKS 端最常見的原因是投射權杖的 aud 與規則不符(請投射一個 audience: https://api.anthropic.com 的權杖,而非 IRSA 預設的 sts.amazonaws.com)。

限定規則的範圍

將規則的 match 區塊鎖定在符合您使用情境的最小範圍:

  • 固定完整的角色 ARN: 使用 subject_prefix: "arn:aws:iam::<account>:role/<role-name>" 且結尾不加 *,使帳戶中的其他角色不會相符。
  • 固定帳戶 ID: 透過 claims 對應表或 CEL condition 比對權杖 https://sts.amazonaws.com/ 宣告中的 aws_account 欄位,作為防範前綴設定錯誤的縱深防禦檢查。
  • 在 EKS 上固定命名空間與服務帳戶: 使用確切的 system:serviceaccount:<namespace>:<name> 值,且在 system:serviceaccount: 前綴之後不加 *
  • 每個環境使用獨立的規則: 為正式、預備與開發環境的工作負載分別建立不同的規則,而非放寬單一前綴來涵蓋全部。

後續步驟

Was this page helpful?