セルフマネージドのKubernetesクラスター(kubeadm、k3s、OpenShift、およびオンプレミスのディストリビューション)は、projected service account tokens(プロジェクトされたサービスアカウントトークン)を通じて、すべてのポッドに対してOIDC JSON Web Token(JWT)に署名します。クラスターのAPIサーバーがOIDC発行者として機能し、各トークンのsubクレームはsystem:serviceaccount:<namespace>:<service-account>の形式に従います。クラスターの発行者URLは、そのディスカバリードキュメントを読むことで確認できます:
kubectl get --raw /.well-known/openid-configuration | jq -r .issuerこのページで説明するメカニズム(プロジェクトされたサービスアカウントトークン、OIDC発行者としてのクラスターAPIサーバー)はKubernetes自体にネイティブなものであるため、すべてのKubernetesディストリビューションの基盤となっています。マネージドKubernetesサービスで実行している場合は、クラウドプロバイダーのガイドでプロバイダー管理の発行者URLの確認場所を説明しています:AWS (EKS)、Google Cloud (GKE)、またはAzure (AKS)。クラスターでSPIREを実行している場合は、クラスターAPIサーバーではなくSPIRE OIDC Discovery Providerが発行者となります。SPIFFEを参照してください。そこに記載されていないその他のディストリビューションやマネージドプロバイダーについては、このガイドに従い、クラスターが報告する発行者URLを使用してください。
--service-account-issuerフラグが設定されたKubernetesクラスター。ほとんどのディストリビューションではこれがデフォルトで設定されています。kubeadmクラスターでは通常https://kubernetes.default.svc.cluster.localが使用されます。APIサーバーの設定に直接アクセスできない場合は、プラットフォームチームが値を確認できます。inlineモードで登録できること(Anthropicを設定するで説明)。フェデレーションルールが期待するオーディエンスと有効期間で、サービスアカウントトークンをポッドにプロジェクトします。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このポッドに対して発行されるトークンには、sub: "system:serviceaccount:inference:inference-worker"とaud: ["https://api.anthropic.com"]が含まれます。
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"}を使用してください。
inlineキーを使用する場合、クラスターがサービスアカウント署名キーをローテーションした際に発行者を更新する責任はお客様にあります。ローテーションはまれ(通常はクラスターのアップグレード時のみ)ですが、新しいJWKSをプッシュするまでトークン交換は署名エラーで失敗します。
フェデレーションルール: サービスアカウントの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をポッドのANTHROPIC_FEDERATION_RULE_ID環境変数に追加します。
Kubernetesを設定するのポッド仕様では、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 を
# ポッドの環境から読み取ります。
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値が返されます。400 invalid_grantが発生した場合は、失敗した交換のトラブルシューティングを参照してください。Kubernetes側で最も一般的な原因はJWKSキーの不一致です(inlineモードの場合は、kubectl get --raw /openid/v1/jwksで再取得して発行者を更新してください)。
subject_prefixがsystem:serviceaccount:*の場合、クラスター内のすべてのサービスアカウントにマッチするため、どのポッドでもフェデレーションされたAnthropicトークンを取得できてしまいます。audienceマッチャーがない場合、このルールはクラスターのデフォルトオーディエンストークンにもマッチします。これはすべてのポッドにすでにプロジェクトされています。
ルールのmatchブロックを、ユースケースに適合する最も狭いスコープに限定してください:
*を付けずに、完全なsystem:serviceaccount:<namespace>:<name>の値を使用します。audienceを必須にし、ポッドのserviceAccountTokenプロジェクションに同じ値を設定して、デフォルトオーディエンストークンが拒否されるようにします。Was this page helpful?