ClaudeのWIFをOktaと連携する手順
Okta service applicationとClient Credentialsフローで、APIキーを使わずClaude APIに認証する設定手順とスコープの絞り方。
OktaとWIFを連携するとは
Workload Identity Federation(WIF)は、sk-ant-... のAPIキーを持たせる代わりに、既存のIdP(アイデンティティプロバイダー)が発行する短命トークンでClaude APIに認証させる仕組みです。Oktaは「サービスアプリケーション」という機械向けのアプリ種別を持ち、OAuth 2.0のclient_credentialsグラントでOIDCアクセストークンを発行します。この記事では、そのOktaトークンをAnthropicのアクセストークンに交換してv1/messagesを呼ぶまでの設定を、Console側とOkta側の両方から追います。
流れは単純です。ワークロードがOktaに認証してJWTを受け取り、そのJWTをAnthropicの/v1/oauth/tokenに渡してsk-ant-oat01-から始まる短命アクセストークンと交換します。APIキーのように長期間有効な文字列を発行・保管・失効させる作業がなくなる点がAPIキー運用との最大の違いです。
前提条件
- OktaのAPI Access Managementが有効な組織アカウント(カスタム認可サーバーの作成に必須)
- Claude Consoleでサービスアカウント・federation issuer・federation ruleを作成できる権限
- Oktaの
/v1/tokenエンドポイントにトークンをリクエストでき、api.anthropic.comに到達できるワークロード
用語の補足: サービスアカウント(svac_...)はAnthropic組織内の人間ではない名前付きID、federation issuer(fdis_...)はOIDCプロバイダーの登録情報、federation rule(fdrl_...)は「issuerからのJWTがこの条件を満たせば、このサービスアカウントとしてトークンを発行する」という対応表です。3つのリソースをConsoleではなくコードから作りたい場合は、WIFをAdmin APIで管理するでサービスアカウント・issuer・ruleそれぞれの作成APIを扱っています。
手順1: Oktaでサービスアプリを作る
- Service app integrationの作成: Okta Admin Consoleで新規アプリ統合をAPI Services(OIDC、machine-to-machine)タイプで作成し、生成されたClient IDを控えます。
- クライアント認証方式の選択: 鍵レスにするならPublic key / Private key(
private_key_jwt)を選び、ワークロードの公開JWKを登録します。シークレットを安全に保管できる環境ならクライアントシークレットでも構いません。検証目的でDPoP要件を一時的に無効化する場合は、本番構成では必ず組織のセキュリティ要件に合わせて戻してください。 - audienceの設定: カスタム認可サーバーでaudienceを
https://api.anthropic.comに設定します。発行されるアクセストークンのaudクレームがこの値になり、Anthropicはこの固定値と照合します。 - scopeの許可: 認可サーバーでサービスアプリがリクエストできるscope(例:
anthropic.access)を最低1つ用意します。許可されたscopeを含まないclient_credentialsリクエストはOktaに拒否されます。 - アクセスポリシーの作成: 手順4のscopeをサービスアプリがリクエストできるルールを持つアクセスポリシーを作成します。
- (任意)カスタムクレームの追加: Client ID以外の値で照合したい場合、認可サーバーのClaimsタブでアクセストークンにクレームを追加します。
client_credentialsを使うサービスアプリでは、Oktaは発行するアクセストークンのsubクレームをアプリケーションのClient IDに、issを認可サーバーの発行者URLにセットします。
手順2: Anthropic側でissuerとruleを作る
Claude ConsoleでSettings → Workload identityを開き、Connect workloadからCustom OIDCを選びます。ウィザードがissuerの登録・サービスアカウントの作成・federation ruleの作成を順に案内します。
ウィザードが作るリソースは、Admin APIから直接送っても同じです。
federation issuer: OktaのカスタムAuthorization Server URLとdiscoveryモードを使います。Anthropicは.well-known/openid-configurationをOktaから読み取り、その中のjwks_uriからJWKSを取得します。
{
"name": "okta-prod",
"issuer_url": "https://acme.okta.com/oauth2/aus1a2b3c4d5e6f7g8h9",
"jwks": { "type": "discovery" }
}federation rule: Oktaのsubクレーム(サービスアプリのClient ID)に一致させます。カスタムクレームを定義していれば、claimsマップやCEL条件式でそちらを照合対象にできます。
{
"name": "okta-pipeline",
"issuer_id": "fdis_...",
"match": {
"subject_prefix": "0oa1b2c3d4e5f6g7h8i9",
"audience": "https://api.anthropic.com"
},
"target": { "type": "service_account", "service_account_id": "svac_..." },
"workspace_id": "wrkspc_...",
"oauth_scope": "workspace:developer",
"token_lifetime_seconds": 600
}手順3: トークンを取得してClaude APIを呼ぶ
AWS・Google Cloud・Kubernetesのようなプラットフォームネイティブなプロバイダーは、ワークロードの実行環境内(投影ファイルやローカルのメタデータエンドポイント)にトークンを自動で用意します。Oktaにはこの仕組みがありません。ワークロード側がOktaのトークンエンドポイントを自分で呼び、取得したJWTをAnthropic SDKに渡す必要があります。
# 1. Oktaからアクセストークンを取得(private_key_jwtによるclient_credentials)
OKTA_JWT=$(curl -sS "https://acme.okta.com/oauth2/aus1a2b3c4d5e6f7g8h9/v1/token" \
-d grant_type=client_credentials \
-d scope=anthropic.access \
-d client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer \
--data-urlencode client_assertion="$SIGNED_CLIENT_ASSERTION" \
| jq -r .access_token)
# 2. OktaのJWTをAnthropicのアクセストークンに交換
ACCESS_TOKEN=$(curl -sS https://api.anthropic.com/v1/oauth/token \
-H "content-type: application/json" \
-d @- <<JSON | jq -r .access_token
{
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": "$OKTA_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"
}
JSON
)
# 3. Claude APIを呼ぶ
curl https://api.anthropic.com/v1/messages \
-H "authorization: Bearer $ACCESS_TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model": "claude-opus-5", "max_tokens": 1024, "messages": [{"role": "user", "content": "Hello, Claude"}]}' \
| jq -r '.content[] | select(.type == "text") | .text'SDKはAnthropicのアクセストークンが期限切れに近づくたびに、登録したidentity-tokenプロバイダーを呼び直します。したがってOktaのトークン取得処理は、トークンをキャッシュせず呼ばれるたびに新しいトークンを返す実装にします。ant CLIを使う場合はANTHROPIC_IDENTITY_TOKEN_FILEを毎回再読み込みするので、長時間起動しっぱなしのシェルではこのファイルをタイマーで更新してください。
検証方法とエラーの見分け方
交換に成功するとsk-ant-oat01-で始まるaccess_tokenと、秒単位のexpires_inが返ります。交換が失敗すると401のauthentication_error(メッセージはAuthentication failed)という不透明な応答になるため、原因はレスポンス本文からは分かりません。Claude Consoleの認証履歴ページ(Settings → Workload identity → History)で拒否理由を確認します。
Okta側で最も多い原因は、issuer_urlの指定ミスです。パスに/oauth2/<auth-server-id>を含めず、Oktaの組織認可サーバー(/oauth2/v1/token)をそのまま指定すると、署名鍵が公開されていないため検証できません。
ルールのスコープを絞る
ルールのmatchブロックは、ユースケースに合う最も狭い範囲に絞ります。
- Client IDを固定する:
subject_prefixにサービスアプリの完全なClient IDを、末尾の*なしで設定する - audienceを固定する: 認可サーバーに設定したaudience値と一致させ、別のaudience向けに発行されたトークンを拒否する
- カスタムクレームで絞る: より細かく制御したい場合は、認可サーバーのClaimsタブでクレームを追加し、ルールの
claimsマップやCEL条件式で照合する - サービスアプリごとに1ルール: 複数のサービスアプリで1つのルールを共有せず、サービスアプリごとに個別のfederation ruleを作る
よくあるつまずき
| つまずき | 原因 | 対処 |
|---|---|---|
| 401 authentication_error | 原因issuer_urlが組織認可サーバーを指している | 対処パスに /oauth2/<auth-server-id> を含むカスタム認可サーバーのURLに変更する |
| client_credentialsがOktaに拒否される | 原因認可サーバーに許可済みscopeが1つも無い | 対処Claimsタブでscopeを1つ以上作成しアクセスポリシーで許可する |
| ruleが想定外のアプリにもマッチする | 原因subject_prefixを未設定のまま公開 | 対処Client IDを末尾*なしで固定するか、audience・カスタムクレームを追加する |
| DPoP要件でトークン取得が失敗する | 原因検証環境でDPoPが有効なまま | 対処検証時のみ無効化し、本番設定は組織のセキュリティ基準に戻す |
Oktaと他のIdPをどう使い分けるか
すでにOktaでワークフォースIDを一元管理している組織なら、サービスアプリを追加登録するだけでWIFに参加でき、鍵の配布や失効の運用をOkta側の既存プロセスに乗せられます。一方でKubernetesクラスタ内で完結するワークロードは、クラスタが発行する投影済みサービスアカウントトークンをそのまま使う方が構成要素が少なく済みます。CLIやSDKからのワークロード管理そのものを自動化したいなら、ant CLIの認証設定でプロファイル運用の基本も押さえておくと、Oktaのfederation ruleを--profile adminのような専用シェルから安全に叩き分けられます。
まとめ
Oktaとの連携は、他のプラットフォームネイティブなWIFプロバイダーと違い「ワークロードが自分でOktaのトークンエンドポイントを呼ぶ」実装が必須になる点が特徴です。カスタム認可サーバーの用意、audienceとscopeの設定、そしてsubject_prefixによるサービスアプリ単位のルール分離という3点を押さえれば、既存のOkta基盤をそのままAnthropicの認証基盤に転用できます。
APIキーからの移行を検討している場合は、既存のキーを残したままfederationを並行稼働させ、ant auth status で実際にどちらの資格情報が使われているかを確認してから ANTHROPIC_API_KEY を外すのが安全です。CIやKubernetesなど他のIdPと組み合わせて使う組織は、WIFリファレンスでクレデンシャルの解決順序も合わせて確認してください。