AWS 工作負載可以透過交換 AWS 簽署的 OIDC 身分權杖來向 Claude API 進行驗證,而無需使用靜態 API 金鑰。建議的方式是呼叫 AWS STS GetWebIdentityToken API,此方式適用於任何具有 AWS 憑證的工作負載:Lambda、EC2、ECS 和 EKS。EKS 工作負載也可以選擇使用 Kubernetes 投影權杖方式,此方式的設定步驟較少,但僅能在 Pod 內運作。
本指南將說明這兩種方式。如需了解基礎概念(服務帳戶、聯合簽發者和聯合規則),請參閱 Workload Identity Federation。
aws CLI 或 AWS SDK。AWS STS GetWebIdentityToken API 會傳回由 AWS 簽署的 OIDC 權杖,用以聲明呼叫者的 IAM 身分。由於它使用工作負載的環境 AWS 憑證,因此同一套整合方式可涵蓋 Lambda、EC2、ECS 和 EKS。
為帳戶啟用對外 Web 身分聯合
這是帳戶層級的旗標,預設為關閉。在 AWS 主控台中,開啟 IAM,選擇 Account settings(帳戶設定),然後啟用 Outbound web identity federation(對外 Web 身分聯合)。若要以程式方式啟用:
python3 -c "import boto3; boto3.client('iam').enable_outbound_web_identity_federation()"如果未啟用此設定,呼叫 GetWebIdentityToken 將會失敗並出現 OutboundWebIdentityFederationDisabledException。
授予工作負載的 IAM 角色呼叫此 API 的權限
將此政策附加到您的 Lambda 函式、EC2 執行個體或 ECS 任務所使用的 IAM 角色:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["sts:GetWebIdentityToken"],
"Resource": "*"
}
]
}找出您帳戶的 STS 簽發者 URL
啟用對外聯合後,IAM > Account settings(帳戶設定)頁面會顯示 Get Token Issuer URL(取得權杖簽發者 URL)欄位,其值的格式為 https://<uuid>.tokens.sts.global.api.aws。此 URL 是您 AWS 帳戶專屬的;請複製它以供下一步使用。若要以程式方式擷取:
python3 -c "import boto3; print(boto3.client('iam').get_outbound_web_identity_federation_info())"依照設定逐步說明,在 Claude Console 中註冊聯合簽發者、建立 Anthropic 服務帳戶,並建立聯合規則。請使用以下 STS 專屬的值。
聯合簽發者: 註冊您在上一步複製的帳戶專屬 STS 簽發者 URL。它會公開一個公用 JWKS 端點,因此請使用探索模式。
{
"name": "aws-sts",
"issuer_url": "https://<uuid>.tokens.sts.global.api.aws",
"jwks_source": "discovery"
}聯合規則: 比對您傳遞給 GetWebIdentityToken 的 audience,以及 sub 宣告中呼叫角色的 IAM 角色 ARN。sub 值是呼叫此 API 之工作負載的 IAM 角色 ARN,格式為 arn:aws:iam::<account>:role/<role-name>。權杖還帶有一個 https://sts.amazonaws.com/ 宣告,其中包含 aws_account、org_id、principal_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 的聯合憑證。權杖提供者是一個可呼叫物件,因此 SDK 會在每次重新整理時重新呼叫 STS。
GetWebIdentityToken 僅在區域性 STS 端點上可用。如果您收到 'STS' object has no attribute 'get_web_identity_token' 或類似錯誤,請將您的 STS 用戶端固定到某個區域(例如 boto3.client("sts", region_name="us-east-1")),並確保您的 AWS SDK 版本夠新,足以包含此 API。
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-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello from AWS"}],
)
print(message.content[0].text)在工作負載內部,直接交換 STS 簽發的權杖並檢查回應:
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 值。若出現 400 invalid_grant,請參閱疑難排解失敗的交換;AWS 端最常見的原因是 iss 不符(帳戶專屬的 STS 簽發者 URL 必須與已註冊的 issuer_url 完全相符)。
如果您的工作負載在 EKS Pod 中執行,您可以略過 STS 呼叫,直接從磁碟讀取 Kubernetes 投影的服務帳戶權杖。Kubernetes 會原生地將與 OIDC 相容的權杖投影到 Pod 中,而 SDK 可以從檔案路徑讀取它,因此不需要權杖提供者可呼叫物件。此方式比 STS 方式少兩個 AWS 設定步驟,但僅能在 Pod 內運作;其底層機制與通用 Kubernetes 整合相同。
此方式額外需要一個已啟用 IAM OIDC 提供者的 EKS 叢集,以及對該叢集的 kubectl 存取權限。
找出您叢集的 OIDC 簽發者 URL
每個 EKS 叢集都有一個唯一的 OIDC 簽發者。使用 AWS 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 註冊為聯合簽發者。
建立服務帳戶並投影具有 Anthropic audience 的權杖
EKS Pod 身分 Webhook 會偵測 eks.amazonaws.com/role-arn 註解,並自動投影一個帶有 aud: sts.amazonaws.com 的權杖,將其路徑公開為 AWS_WEB_IDENTITY_TOKEN_FILE。該權杖用於 AWS 角色擔任。對於 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-workerapiVersion: 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注意權杖的宣告結構
投影的權杖是由您叢集的 OIDC 簽發者簽署的「JSON Web Token」(JSON Web 權杖),即 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
}依照設定逐步說明,在 Claude Console 中註冊聯合簽發者、建立 Anthropic 服務帳戶,並建立聯合規則。請使用以下 EKS 專屬的值。
聯合簽發者: EKS 簽發者會公開一個公用 JWKS 端點,因此請使用探索模式。簽發者 URL 必須與權杖的 iss 宣告完全相符。每個叢集註冊一個簽發者。
{
"name": "prod-eks-uswest2",
"issuer_url": "https://oidc.eks.us-west-2.amazonaws.com/id/6FA42E7BFDE8549CB...",
"jwks_source": "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-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello from EKS"}],
)
print(message.content[0].text)Pod 規格已設定 ANTHROPIC_IDENTITY_TOKEN_FILE、ANTHROPIC_FEDERATION_RULE_ID、ANTHROPIC_ORGANIZATION_ID、ANTHROPIC_SERVICE_ACCOUNT_ID 和 ANTHROPIC_WORKSPACE_ID,因此您可以在不帶任何引數的情況下建構用戶端,SDK 會自動讀取聯合環境變數。
在 Pod 內部,直接交換投影的權杖並檢查回應:
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 值。若出現 400 invalid_grant,請參閱疑難排解失敗的交換;EKS 端最常見的原因是投影權杖的 aud 與規則不符(請投影一個帶有 audience: https://api.anthropic.com 的權杖,而非 IRSA 預設的 sts.amazonaws.com)。
subject_prefix 為 arn:aws:iam::123456789012:role/* 會比對帳戶中的每個 IAM 角色。任何可以擔任任何符合角色的主體都能取得聯合的 Anthropic 權杖。
將規則的 match 區塊鎖定到符合您使用案例的最窄範圍:
subject_prefix: "arn:aws:iam::<account>:role/<role-name>" 且不帶結尾的 *,以避免帳戶中的其他角色被比對到。claims 對應或 CEL condition 比對權杖 https://sts.amazonaws.com/ 宣告中的 aws_account 欄位,作為防範前綴設定錯誤的深度防禦檢查。system:serviceaccount:<namespace>:<name> 值,且在 system:serviceaccount: 前綴後不帶 *。Was this page helpful?
serviceAccountToken 投影會將 aud 設定為 https://api.anthropic.com。位於 AWS_WEB_IDENTITY_TOKEN_FILE 的另一個由 IRSA 注入的權杖帶有 aud: sts.amazonaws.com,用於 AWS API 呼叫,而非此交換。