AI活用全般

Claude APIキーをサーバーに置きっぱなしにしたくない開発チーム向け|Workload Identity Federationで短命トークンに替える6ステップ

Claude APIのWorkload Identity Federationは、CI/CDやKubernetesに長期APIキーを置かず、短命のOIDCトークンでClaude APIを呼ぶための認証方式です。

流れは「外部IdPのJWTを受け取る → Anthropicが署名とルールを検証する → サービスアカウント用の短命アクセストークンを発行する」の3段階です。

ただし移行時にANTHROPIC_API_KEYが残っていると、SDKはAPIキー側を先に選びます。

ここを見落とすと、WIFを設定したつもりで古いキーを使い続けます。

この記事はClaude APIをGitHub Actions、AWS、Kubernetes、社内CIから呼んでいて、APIキーの保管・漏えい・ローテーションを減らしたい開発チーム向けです。

個人のChatGPT風チャット利用ではなく、サーバーやCIからClaude APIを呼ぶ人向けに書きます。

Claude Workload Identity Federationとは何か?

Workload Identity Federation、略してWIFは、Claude APIに渡す認証情報を「長く生きるAPIキー」から「外部のID基盤が発行した短命トークン」に置き換える仕組みです。

Anthropic公式ドキュメントは、WIFを「運用中のIdPが発行する短命のOIDCトークンでClaude APIへ認証する方式」と説明しています。

対象にはAWS IAM、Google Cloud、GitHub Actions、Kubernetes service accounts、Microsoft Entra ID、Oktaなどが並んでいます。

要するに、サーバーやCIにsk-ant-...形式のAPIキーを置かない。

実行環境が持つ身分証明をAnthropic側で検証し、その場限りのsk-ant-oat01-...形式のアクセストークンに交換します。

私の見方では、これは「便利な認証オプション」よりも、Claude APIを本番運用に入れるチーム向けのセキュリティ機能です。

開発者の手元やCI secretsにAPIキーが増え続けているチームほど、導入価値が大きいです。

APIキー認証とWIFは何が違うのか?

違いは「秘密を置くか、実行時に交換するか」です。

項目 APIキー Workload Identity Federation
認証情報 sk-ant-...を環境変数やsecretに保存 外部IdPのJWTを実行時に交換
寿命 削除するまで残る 分単位から最大24時間の短命トークン
漏えい時 キー削除まで使われる恐れがある 上流IdPとWIFルールの両方で縛れる
運用負荷 発行、保管、配布、ローテーションが必要 初期設定後はSDKが交換と更新を処理
向いている場面 個人開発、短期検証 CI、本番サーバー、Kubernetes、AWSワークロード

短命トークンの寿命は、WIFルールのtoken_lifetime_secondsで60秒から86400秒の間に設定します。

デフォルトは3600秒です。

86400秒は24時間です。

3600秒は1時間です。

ただし公式ドキュメントでは、発行されるAnthropicトークンの寿命は「ルール側の寿命」と「提示したIdP JWTの残り寿命の2倍」の短い方になるとされています。

つまり、上流のJWTが短いのにAnthropic側だけ長く生きる、という設計にはなっていません。

ここはかなり実務寄りです。

GitHub ActionsのOIDCトークンは短命なので、長時間ジョブではJWTファイルを更新し続ける設計が必要になります。

WIFの仕組みは3つの部品で見るとわかりやすい

Anthropic Console側で設定する部品は3つです。

  1. Service account: Claude APIを実行する非人間ユーザー。svac_...形式のIDを持つ
  2. Federation issuer: JWTを発行する外部IdP。fdis_...形式のIDを持つ
  3. Federation rule: どのJWTをどのService accountに対応させるかを決めるルール。fdrl_...形式のIDを持つ

公式の説明を短く言い換えると、「issuer Xが署名し、claimsがYに見えるJWTだけ、service account ZとしてClaude APIを呼ばせる」です。

このYの部分が重要です。

GitHub Actionsならrepo:your-org/your-repo:ref:refs/heads/mainのようなsubを見ます。

Kubernetesならsystem:serviceaccount:<namespace>:<service-account>のようなsubを見ます。

AWS STSなら呼び出し元IAM role ARNがsubになります。

私なら最初の設計で、issuerを環境ごとに分けます。

本番EKS、ステージングEKS、GitHub Actionsを1つのissuerに寄せない。

公式も「production EKS cluster、staging cluster、GitHub Actionsは別issuer」の例を出しています。

GitHub Actionsで使うならどこを絞るべきか?

GitHub Actionsは一番わかりやすい導入先です。

GitHubはhttps://token.actions.githubusercontent.comをissuerとしてOIDCトークンを発行します。

workflow側ではid-token: writeを付け、https://api.anthropic.comをaudienceにしてJWTを取得します。

permissions:
  id-token: write
  contents: read

steps:
  - name: Fetch GitHub OIDC token
    run: |
      curl -sS -H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
        "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=https://api.anthropic.com" \
        | jq -r .value > /tmp/gha-jwt

Anthropic側のissuerはこうなります。

{
  "name": "github-actions",
  "issuer_url": "https://token.actions.githubusercontent.com",
  "jwks_source": "discovery"
}

ルールは広げすぎない方がいいです。

公式ドキュメントは、repo:your-org/*だけで許可すると、organization内の全リポジトリに広がり、ref制約がなければfork由来のpull request実行も巻き込む恐れがあると警告しています。

ここは10分かけてでも絞る場所です。

絞り方 防げる事故
リポジトリ固定 repo:your-org/your-repo:* 別リポジトリからの利用
ブランチ固定 ref: refs/heads/main feature branchやPR実行
owner固定 repository_owner: your-org claim解釈の揺れ
environment固定 environment: production 承認なしdeploy job

私なら最初はmainブランチだけにします。

PR上でClaude APIを呼ぶ必要がある場合も、いきなり全PRに開けず、別Service accountと別Workspaceで使用量を分けます。

AWSで使うならSTS経由とEKS projected tokenの2択になる

AWS向け公式ガイドでは、推奨ルートとしてAWS STSのGetWebIdentityTokenを使う方法が示されています。

Lambda、EC2、ECS、EKSのどこでも、ワークロードがAWS credentialsを持っていれば同じ流れでOIDCトークンを取得できます。

準備は3段階です。

  1. AWS accountでOutbound web identity federationを有効化する
  2. ワークロードのIAM roleにsts:GetWebIdentityTokenを許可する
  3. account固有のissuer URL、例https://<uuid>.tokens.sts.global.api.awsをAnthropic側に登録する

AWS側で有効化していないと、OutboundWebIdentityFederationDisabledExceptionで止まります。

公式サンプルでは、GetWebIdentityTokenhttps://api.anthropic.comをaudienceとして渡し、返ったWebIdentityTokenをSDKのWorkloadIdentityCredentialsへ渡します。

1つ注意があります。

AWSガイドは、このAPIがregional STS endpointで使えると書いています。

STS object has no attribute get_web_identity_tokenのようなエラーが出る場合は、us-east-1などのregionを明示し、SDKが古くないか確認します。

EKSだけならKubernetes projected service account tokenルートもあります。

こちらはPod内にaudience: https://api.anthropic.comのJWTを投影し、ANTHROPIC_IDENTITY_TOKEN_FILEでSDKに読ませます。

AWS全体で揃えたいならSTS、EKS Pod内だけならprojected token、という分け方が現実的です。

Kubernetesではどの値を見ればいいのか?

KubernetesのWIFは、ServiceAccount tokenをPodへ投影して使います。

Anthropic公式のKubernetesガイドでは、Pod内のJWTのsubsystem:serviceaccount:<namespace>:<service-account>になると説明されています。

volumes:
  - name: anthropic-token
    projected:
      sources:
        - serviceAccountToken:
            audience: https://api.anthropic.com
            expirationSeconds: 3600
            path: token

コンテナ側ではこのファイルを環境変数で渡します。

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_...

自前Kubernetesやオンプレ環境では、issuer URLがhttps://kubernetes.default.svc.cluster.localのように外から届かない場合があります。

この場合、AnthropicがJWKSを取りに行けないので、inlineモードで鍵を登録します。

inlineモードは便利ですが、鍵ローテーションが自動ではありません。

WIF referenceでも、inlineではIdPの署名鍵が変わったらissuer設定を更新しないと交換が失敗すると書かれています。

ここは運用負荷が出ます。

社内Kubernetesでinlineを選ぶなら、「鍵更新時にAnthropic issuer設定を誰が更新するか」まで決めてから入れます。

移行手順はどう進めると事故りにくいか?

既存のClaude APIキー運用からWIFへ切り替えるなら、私はこの順番で進めます。

  1. WIFを並行設定する。issuer、service account、federation ruleを作る。既存APIキーはまだ消さない
  2. 対象ワークロードのJWTを1つデコードするisssubaud、GitHubならrepository_ownerrefを確認する
  3. ルールを狭く作る。最初から*に逃げない。本番1リポジトリ、mainブランチ、1namespaceなどに絞る
  4. SDKの認証元を確認するant auth statusやSDKログで、APIキーではなくWIFが勝っているか見る
  5. ANTHROPIC_API_KEYを外す。CI secrets、Pod env、shell profile、コンテナ環境を確認する
  6. APIキーを削除する。WIFで動いていることを確認してからClaude Consoleで古いキーを消す

最大の落とし穴は4と5です。

WIF referenceでは、SDKの認証優先順位が明記されています。

constructor引数の次にANTHROPIC_API_KEYANTHROPIC_AUTH_TOKENがあり、その下にWIF環境変数があります。

つまり、WIFの環境変数を全部入れても、古いANTHROPIC_API_KEYが残っていればAPIキー側が勝ちます。

空文字も危険です。

公式referenceでは、ANTHROPIC_API_KEY=""のように空文字でexportされていても、そのスロットを占有すると説明されています。

外す時は空文字ではなくunset ANTHROPIC_API_KEYです。

よくある失敗はどこで起きるのか?

症状 原因 見る場所
WIFではなくAPIキーで認証される ANTHROPIC_API_KEYが残っている 環境変数、CI secrets、ant auth status
no credentials WIF必須変数が足りない ANTHROPIC_FEDERATION_RULE_IDなど4点
invalid_grant iss不一致、JWKS取得失敗、claim不一致 Authentication history、JWTデコード結果
403 トークンのscope外、workspace不一致 ruleのoauth_scopeとworkspace
長時間jobの途中で失敗 JWTファイルが更新されていない GitHub Actionsのtoken再取得処理

公式referenceでは、invalid_grantは意図的に詳細を返さないと書かれています。

理由をレスポンスだけで当てようとすると時間が溶けます。

先にClaude ConsoleのAuthentication historyを見ます。

そこにissuer、rule、検査したJWT claims、失敗した検証ステップが出ます。

次にJWTをデコードして、issが登録したissuer URLと1文字単位で一致するか、audが完全一致するか、subがruleに合うかを見ます。

30秒のclock skewもあります。

JWTのexpnbfiatは30秒の猶予付きで検証されます。

ワークロード側の時刻ずれが大きいと、設定が正しくても失敗します。

WIFを入れるべきチームと、まだAPIキーでいいチームは?

全員が今すぐWIFへ移る必要はありません。

状況 判断 理由
個人の検証スクリプト APIキーで十分 WIF設定の方が重い
GitHub ActionsでClaude APIを呼ぶ WIF推奨 repo secretsに長期キーを置かずに済む
EKSやGKEの本番Podから呼ぶ WIF推奨 ServiceAccount単位で縛れる
AWS Lambda、ECS、EC2から呼ぶ STS WIFを検討 IAM roleを身分証明に使える
社内のオンプレKubernetes 要設計 inline JWKSの鍵更新運用が必要

私なら、最初の導入候補はGitHub Actionsです。

WIFの価値が見えやすく、issuer URLも固定で、GitHub側のOIDC claimも読みやすいからです。

次に本番Kubernetes。

最後にAWS横断です。

AWS STSルートは強いですが、Outbound web identity federationの有効化、IAM権限、SDKバージョン確認が入るので、組織内のAWS管理権限が必要になります。

FAQ

Q1. WIFを使えばClaude APIキーは完全に不要になりますか?

対象ワークロードでは不要にできます。

代わりに外部IdPのJWTをAnthropicの/v1/oauth/tokenへ交換し、短命のAnthropicアクセストークンでClaude APIを呼びます。

ただし個人検証や移行期間ではAPIキーを併用する場面もあります。

Q2. WIFのアクセストークンは何分持ちますか?

WIFルールのtoken_lifetime_secondsは60秒から86400秒です。

デフォルトは3600秒です。

ただし実際の寿命は上流IdP JWTの残り寿命にも制限されます。

Q3. GitHub Actionsで一番危ない設定は何ですか?

subject_prefix: repo:your-org/*のように広く許可し、ref制約を置かない設定です。

公式ドキュメントは、fork由来のpull request実行まで巻き込む恐れがあると警告しています。

repo、branch、owner、environmentで絞ります。

Q4. ANTHROPIC_API_KEYを空文字にすればWIFへ切り替わりますか?

切り替わりません。

WIF referenceでは、空文字の認証環境変数も優先順位のスロットを占有すると説明されています。

空文字代入ではなく、環境変数そのものをunsetします。

Q5. 403が出たらJWTの設定ミスですか?

JWT交換が成功した後の403なら、scopeやworkspaceの不一致を疑います。

WIF referenceでは、workspace:developerが非管理系Claude API endpointsに対応し、scope外endpointは403になると説明されています。

このページに出てきた言葉

Workload Identity Federation
CIやサーバーなどの実行環境が持つ身分証明を使い、Claude API用の短命アクセストークンへ交換する認証方式
JWT
署名付きのトークン形式。issuer、subject、audience、有効期限などのclaimsを含み、Anthropicが署名と中身を検証する
JWKS
JWTの署名検証に使う公開鍵セット。discovery、explicit URL、inlineの3方式でAnthropicへ渡す
Service account
人間ではないClaude組織内の実行主体。WIFで発行されたトークンは、このservice accountとして動く
Federation issuer
JWTを発行する外部IdPの登録情報。issuer URLとJWKS取得方法を持つ
Federation rule
JWTのsubject、audience、claims、CEL条件などを見て、どのservice accountへ対応させるかを決めるルール
subject prefix
JWTのsub claimに対する一致条件。GitHub Actionsならrepoとbranch、Kubernetesならnamespaceとservice accountの絞り込みに使う
OAuth scope
発行されたアクセストークンが呼べるClaude APIの範囲。2026年5月時点のWIFではworkspace:developerが使われる

参考リンク

※この記事の内容は執筆時点のものです。AIは進化が速い分野のため、最新の仕様は公式サイトでご確認ください。

-AI活用全般
-, , ,

← 戻る