GitHub ActionsでWIFを使用する
長期間有効なAPIキーの代わりに、短期間有効なIDトークンを使用してGitHub ActionsワークフローをClaude APIに対して認証します。
すべてのGitHub Actionsワークフロー実行は、https://token.actions.githubusercontent.com にあるGitHubのホスト型発行者から署名付きIDトークンを要求できます。「Workload Identity Federation」(ワークロードIDフェデレーション)を使用すると、ワークフローはそのトークンを短期間有効なAnthropicアクセストークンと交換するため、リポジトリに ANTHROPIC_API_KEY シークレットを保存することなく、CIジョブからClaude APIを呼び出すことができます。
トークンの sub クレームには、リポジトリとトリガーのコンテキストがエンコードされています。ブランチへのプッシュの場合、repo:<owner>/<repo>:ref:refs/heads/<branch> という形式になります。プルリクエストの実行では repo:<owner>/<repo>:pull_request が使用され、環境でゲートされたデプロイメントでは repo:<owner>/<repo>:environment:<name> が使用されます。フェデレーションルールは、このクレーム(および repository_owner や ref などの他のクレーム)と照合して、どのワークフロー実行に認証を許可するかを決定します。
前提条件
- WIFの概念(サービスアカウント、フェデレーション発行者、フェデレーションルール)を理解していること。
- ワークフローファイルを編集でき、
id-token: write権限を付与できるGitHubリポジトリ。 - Anthropicの組織に対して、Claude Consoleでサービスアカウント、フェデレーション発行者、フェデレーションルールを作成する権限。
- Anthropicの組織ID。Claude Consoleの Settings → Organization で確認できます。
ワークフローを設定する
GitHubは、明示的に要求したジョブにのみIDトークンを発行します。ワークフローレベルまたはジョブレベルで id-token: write 権限を追加します。
permissions:
id-token: write
contents: readジョブ内では、ランナーが ACTIONS_ID_TOKEN_REQUEST_URL と ACTIONS_ID_TOKEN_REQUEST_TOKEN という2つの環境変数を公開します。リクエストトークンをベアラー認証情報として、選択したオーディエンスをクエリパラメータとして指定してリクエストURLを呼び出し、返された「JSON Web Token」(JSONウェブトークン)、すなわちJWTをファイルに書き込みます。
- 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-jwtJavaScriptを使用したい場合は、actions/github-script が core.getIDToken(audience) を通じて同じ機能を公開しています。
- name: Fetch GitHub OIDC token
uses: actions/github-script@v8
with:
script: |
const fs = require('fs');
const token = await core.getIDToken('https://api.anthropic.com');
fs.writeFileSync('/tmp/gha-jwt', token);デコードされたトークンには、ワークフロー実行を記述するクレームが含まれています。フェデレーションルールはこれらと照合します。
{
"iss": "https://token.actions.githubusercontent.com",
"sub": "repo:your-org/your-repo:ref:refs/heads/main",
"aud": "https://api.anthropic.com",
"repository": "your-org/your-repo",
"repository_owner": "your-org",
"ref": "refs/heads/main",
"sha": "abc123...",
"workflow": "CI",
"actor": "octocat",
"event_name": "push"
}sub 形式の完全な一覧については、GitHubのOIDCサブジェクトクレームリファレンスを参照してください。
Anthropicを設定する
Claude Consoleで Settings → Workload identity を開き、Connect workload をクリックして、GitHub Actions タイルを選択します。ウィザードが、発行者の登録、サービスアカウントの作成、フェデレーションルールの作成を順に案内します。
ウィザードがこれらのリソースを作成します。ウィザードに入力する場合でも、Admin APIに送信する場合でも、以下の値を使用してください。
フェデレーション発行者: GitHubはOIDCディスカバリードキュメントとJWKSを公開しているため、ディスカバリーモードを使用します。GitHubが鍵をローテーションすると、Anthropicは自動的に鍵を更新します。
{
"name": "github-actions",
"issuer_url": "https://token.actions.githubusercontent.com",
"jwks": { "type": "discovery" }
}フェデレーションルール: 信頼する予定のワークフロー実行のみに一致させます。これらのクレームを安全にスコープ設定する方法については、認証できるワークフローを制限するを参照してください。
{
"name": "gha-main",
"issuer_id": "fdis_...",
"match": {
"subject_prefix": "repo:your-org/your-repo:ref:refs/heads/main",
"audience": "https://api.anthropic.com",
"claims": {
"repository_owner": "your-org"
}
},
"target": {
"type": "service_account",
"service_account_id": "svac_..."
},
"workspace_id": "wrkspc_...",
"oauth_scope": "workspace:developer",
"token_lifetime_seconds": 600
}ワークロードが許す限り具体的に指定してください。sub の末尾セグメントは ref:...、environment:...、pull_request の各イベント間で異なるため、同じリポジトリからの複数のイベントタイプにルールを一致させる必要がある場合にのみ、subject_prefix を repo:your-org/your-repo:* に緩めてください(claims.ref 制約と組み合わせて使用します)。
トークンを取得して使用する
ジョブにフェデレーション用の環境変数を設定し、通常どおりSDKを呼び出します。Anthropic() は ANTHROPIC_IDENTITY_TOKEN_FILE を読み取り、最初のリクエスト時にJWTを交換し、有効期限が切れる前にアクセストークンを自動的に更新します。
import anthropic
# ANTHROPIC_FEDERATION_RULE_ID、ANTHROPIC_ORGANIZATION_ID、
# ANTHROPIC_SERVICE_ACCOUNT_ID、ANTHROPIC_WORKSPACE_ID、ANTHROPIC_IDENTITY_TOKEN_FILEを
# ジョブ環境から読み取ります。
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"))GitHubが発行する各IDトークンは、発行後およそ5分で有効期限が切れます。トークンリクエストエンドポイント(ACTIONS_ID_TOKEN_REQUEST_URL)はジョブ全体を通じて有効なままなので、いつでも新しいトークンを取得できます。SDKは初回使用時にトークンを交換し、得られたAnthropicアクセストークンをキャッシュします。Anthropicトークンの有効期間より長く実行されるジョブの場合、SDKは更新のたびに ANTHROPIC_IDENTITY_TOKEN_FILE を再読み込みするため、取得ステップを定期的に再実行する(またはバックグラウンドループでラップする)ことでファイルを最新の状態に保ってください。あるいは、ファイルパスを使用する代わりに、ACTIONS_ID_TOKEN_REQUEST_URL を直接呼び出すトークンプロバイダーコールバックをSDKに渡すこともできます。
セットアップを検証する
交換が成功すると、sk-ant-oat01- で始まる access_token と、秒単位の expires_in 値が返されます。交換が拒否された場合は、どのチェックが失敗したかにかかわらず、固定メッセージ Authentication failed を持つ不透明な 401 authentication_error が返されます。ほとんどの場合、拒否理由は認証履歴ページの該当試行のエントリに記録されており、失敗した交換のトラブルシューティングではチェックを順番に確認できます。GitHub Actions側で最も一般的な原因は、sub クレームの形式が一致しないことです(末尾セグメントは ref:...、environment:...、pull_request の各イベント間で異なります)。この場合、履歴エントリには理由として match_subject_prefix が表示されます。
認証できるワークフローを制限する
ルールの match ブロックを、ユースケースに適合する最も狭いスコープに固定してください。
- 単一のリポジトリに固定する:
subject_prefix: "repo:your-org/your-repo:*"を使用して、組織内の他のリポジトリが一致しないようにします。 - 保護されたブランチに固定する:
claimsの下に"ref": "refs/heads/main"(またはリリースブランチ)を追加して、プルリクエスト実行やフィーチャーブランチが一致しないようにします。 - オーナーを明示的に固定する:
subの解析におけるエッジケースに対する多層防御のチェックとして、claimsの下に"repository_owner": "your-org"を追加します。 - デプロイメント環境に固定する: デプロイジョブの場合、
subject_prefix: "repo:your-org/your-repo:environment:production"に一致させ、GitHubで必須レビュアーを設定してその環境をゲートします。
次のステップ
- Workload Identity Federation:完全なセットアップ手順、環境変数、認証情報の優先順位。
- 認証:フェデレーションとAPIキーの比較。
Was this page helpful?