AWSワークロードは、AWSが署名したOIDCアイデンティティトークンを交換することで、静的なAPIキーなしでClaude APIに対して認証できます。推奨される方法はAWS STSのGetWebIdentityToken APIを呼び出すもので、ワークロードがAWS認証情報を持つあらゆる場所(Lambda、EC2、ECS、EKS)で機能します。EKSワークロードは代わりにKubernetesプロジェクテッドトークンの方法を使用することもできます。こちらは設定手順が少ないですが、Pod内でのみ機能します。
このガイドでは両方の方法を示します。基礎となる概念(サービスアカウント、フェデレーション発行者、フェデレーションルール)については、Workload Identity Federationを参照してください。
aws CLIまたはAWS SDK。AWS STSのGetWebIdentityToken APIは、呼び出し元のIAMアイデンティティを表明する、AWSが署名したOIDCトークンを返します。ワークロードの環境にあるAWS認証情報を使用するため、同じ統合でLambda、EC2、ECS、EKSをカバーできます。
アカウントのアウトバウンドWebアイデンティティフェデレーションを有効にする
これはアカウントレベルのフラグで、デフォルトでは無効です。AWSコンソールでIAMを開き、Account settingsを選択して、Outbound web identity federationを有効にします。プログラムで有効にするには:
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ページにhttps://<uuid>.tokens.sts.global.api.awsという形式の値を持つGet Token Issuer URLフィールドが表示されます。このURLはAWSアカウントごとに一意です。次のステップのためにコピーしてください。プログラムで取得するには:
python3 -c "import boto3; print(boto3.client('iam').get_outbound_web_identity_federation_info())"Claude ConsoleでSettings → Workload identityを開き、Connect workloadをクリックして、AWSタイルを選択します。ウィザードが発行者の登録、サービスアカウントの作成、フェデレーションルールの作成を順に案内します。
ウィザードがこれらのリソースを作成します。ウィザードに入力する場合でも、Admin API に送信する場合でも、以下の値を使用してください。
フェデレーション発行者: 前のステップでコピーしたアカウントごとのSTS発行者URLを登録します。これは公開JWKSエンドポイントを公開しているため、ディスカバリーモードを使用してください。
{
"name": "aws-sts",
"issuer_url": "https://<uuid>.tokens.sts.global.api.aws",
"jwks": { "type": "discovery" }
}フェデレーションルール: GetWebIdentityTokenに渡すオーディエンスと、subクレーム内の呼び出し元ロールのIAMロールARNをマッチさせます。subの値は、APIを呼び出したワークロードのIAMロールARNで、arn:aws:iam::<account>:role/<role-name>という形式です。トークンにはaws_account、org_id、principal_id、および渡したrequest_tagsを含むhttps://sts.amazonaws.com/クレームも含まれています。より細かい制御のために、ルールの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をオーディエンスとして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-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が発行したトークンを直接交換してレスポンスを確認します:
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の設定手順が2つ少ないですが、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オーディエンスのトークンをプロジェクトする
EKSのPodアイデンティティWebhookはeks.amazonaws.com/role-arnアノテーションを検出し、aud: sts.amazonaws.comを持つトークンを自動的にプロジェクトして、そのパスをAWS_WEB_IDENTITY_TOKEN_FILEとして公開します。そのトークンはAWSロールの引き受け用です。Anthropicとの交換のためには、audience: https://api.anthropic.comを持つ2つ目のトークンをプロジェクトし、専用のパスにマウントします。
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(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呼び出し用であり、この交換用ではありません。
Claude ConsoleでSettings → Workload identityを開き、Connect workloadをクリックして、AWSタイルを選択します。ウィザードが発行者の登録、サービスアカウントの作成、フェデレーションルールの作成を順に案内します。
ウィザードがこれらのリソースを作成します。ウィザードに入力する場合でも、Admin API に送信する場合でも、以下の値を使用してください。
フェデレーション発行者: EKSの発行者は公開JWKSエンドポイントを公開しているため、ディスカバリーモードを使用してください。発行者URLはトークンのissクレームと正確に一致する必要があります。クラスターごとに1つの発行者を登録してください。
{
"name": "prod-eks-uswest2",
"issuer_url": "https://oidc.eks.us-west-2.amazonaws.com/id/6FA42E7BFDE8549CB...",
"jwks": { "type": "discovery" }
}フェデレーションルール: KubernetesのsubクレームとAnthropicのオーディエンスhttps://api.anthropic.comをマッチさせます。(そのオーディエンスを持つ専用のサービスアカウントトークンをプロジェクトしてください。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仕様はすでに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がルールと一致していないことです(IRSAのデフォルトであるsts.amazonaws.comではなく、audience: https://api.anthropic.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:プレフィックスの後に*を付けず、正確なsystem:serviceaccount:<namespace>:<name>の値を使用します。Was this page helpful?