KubernetesでWIFを使用する
投影されたサービスアカウントトークンを使用して、セルフマネージドKubernetesクラスターからClaude APIに認証します。
セルフマネージドKubernetesクラスター(kubeadm、k3s、OpenShift、およびオンプレミスディストリビューション)は、projected service account tokens(投影されたサービスアカウントトークン)を通じて、すべてのPodに対してOIDC「JSON Web Token」(JSON Webトークン)、すなわちJWTに署名します。クラスターのAPIサーバーがOIDC発行者(issuer)として機能し、各トークンの sub クレームは system:serviceaccount:<namespace>:<service-account> の形式に従います。クラスターの発行者URLは、ディスカバリードキュメントを読み取ることで確認できます。
kubectl get --raw /.well-known/openid-configuration | jq -r .issuer前提条件
- WIFの概念(サービスアカウント、フェデレーション発行者、フェデレーションルール)に精通していること。
- APIサーバーで
--service-account-issuerフラグが設定されたKubernetesクラスター。ほとんどのディストリビューションではデフォルトで設定されています。kubeadmクラスターは通常https://kubernetes.default.svc.cluster.localを使用します。APIサーバーの設定に直接アクセスできない場合は、プラットフォームチームが値を確認できます。 - Anthropicがトークン署名を検証できるように、次のいずれかを満たすこと:
- 発行者のJWKSエンドポイントがパブリックインターネットからHTTPSのポート443で到達可能であること、または
- クラスター内部からJWKSを取得し、
inlineモードで登録できること(Anthropicを設定するで説明します)。
- Anthropic組織のClaude Consoleでサービスアカウント、フェデレーション発行者、フェデレーションルールを作成する権限。
Kubernetesを設定する
フェデレーションルールが期待するオーディエンスと有効期間を指定して、サービスアカウントトークンをPodに投影します。serviceAccountToken プロジェクションは新しいJWTをマウントパスに書き込み、expirationSeconds が経過する前にローテーションします。
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このPodに対して発行されるトークンには sub: "system:serviceaccount:inference:inference-worker" と aud: ["https://api.anthropic.com"] が含まれます。
Anthropicを設定する
Claude Consoleで Settings → Workload identity を開き、Connect workload をクリックして、Kubernetes タイルを選択します。ウィザードが発行者の登録、サービスアカウントの作成、フェデレーションルールの作成を順に案内します。
ウィザードがこれらのリソースを作成します。ウィザードに入力する場合でも、Admin APIに送信する場合でも、以下の値を使用してください。
フェデレーション発行者: 多くのセルフマネージドクラスターは、https://kubernetes.default.svc.cluster.local のようなパブリックインターネットから到達できない発行者URLを使用しています。お使いのクラスターがこれに該当する場合は、inline JWKSソースを選択し、クラスターの鍵を貼り付けます。クラスター内部から取得してください。
kubectl get --raw /openid/v1/jwks次に、返された keys 配列の内容(外側の {"keys": [...]} ラッパーではなく)を使用して発行者を設定します。
{
"name": "onprem-k8s",
"issuer_url": "https://kubernetes.default.svc.cluster.local",
"jwks": {
"type": "inline",
"keys": [{ "kty": "RSA", "kid": "...", "n": "...", "e": "AQAB" }]
}
}inline モードでは、issuer_url はJWTの iss クレームと比較されるだけで、Anthropicがそこに到達を試みることはありません。発行者がパブリックに到達可能な場合は、代わりに "jwks": {"type": "discovery"} を使用してください。
フェデレーションルール: サービスアカウントの sub クレームと、投影されたトークンに設定したオーディエンスに一致させます。
{
"name": "onprem-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:* に緩めてください(末尾の * によりプレフィックス一致になります)。ルールの fdrl_... IDをPodの ANTHROPIC_FEDERATION_RULE_ID 環境変数に追加します。
トークンを取得して使用する
Kubernetesを設定するのPod仕様では、ANTHROPIC_IDENTITY_TOKEN_FILE を投影されたマウントパスに設定し、あわせて ANTHROPIC_FEDERATION_RULE_ID、ANTHROPIC_ORGANIZATION_ID、ANTHROPIC_SERVICE_ACCOUNT_ID、ANTHROPIC_WORKSPACE_ID も設定しています。これらが設定されていれば、SDKは交換のたびにディスクからトークンを読み取り、Anthropicアクセストークンを自動的に更新します。
import anthropic
# ANTHROPIC_IDENTITY_TOKEN_FILE、ANTHROPIC_FEDERATION_RULE_ID、
# ANTHROPIC_ORGANIZATION_ID、ANTHROPIC_SERVICE_ACCOUNT_ID、ANTHROPIC_WORKSPACE_IDを
# Podの環境変数から読み取ります。
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(next(block.text for block in message.content if block.type == "text"))セットアップを検証する
交換が成功すると、sk-ant-oat01- で始まる access_token と、秒単位の expires_in 値が返されます。交換が不透明な 401 authentication_error レスポンス(メッセージ Authentication failed)で失敗した場合は、認証履歴ページで拒否理由を確認し、失敗した交換のトラブルシューティングを参照してください。Kubernetes側で最も一般的な原因はJWKS鍵の不一致です(inline モードの場合は、kubectl get --raw /openid/v1/jwks で再取得して発行者を更新してください)。
ルールのスコープを絞る
ルールの match ブロックを、ユースケースに適合する最も狭いスコープに固定してください。
- 名前空間とサービスアカウント名を固定する: 末尾の
*を付けずに、完全なsystem:serviceaccount:<namespace>:<name>の値を使用します。 - 常にオーディエンスを設定する: ルールで
audienceを必須とし、PodのserviceAccountTokenプロジェクションにも同じ値を設定して、デフォルトオーディエンストークンが拒否されるようにします。 - 名前空間ごとに別のルールを使用する: 1つのルールを広げるのではなく、名前空間ごとに個別のルールとAnthropicサービスアカウントを作成します。
- inline JWKS発行者を1つのクラスターにスコープする: 複数のクラスターが発行者URLを共有している場合は、各クラスターのJWKSをそれぞれ独自のフェデレーション発行者として登録し、ルールをその発行者のみにバインドします。
次のステップ
- Workload Identity Federation:概念、トークン交換フロー、SDK設定オプション。
- WIFリファレンス:環境変数、JWKSソースモード、ルール一致モード。
Was this page helpful?