エージェントに渡す鍵の形——短期・スコープ・上限の三点セット
AWS Japan の認可疲れ論、Retty の $OPENAI_API_KEY 廃止、Gemini の無制限キー拒否——同じ週の三つの話は同じ一点を指す。権限はダイアログではなく鍵の形に。600 秒・300 秒・3600 秒から設計と請求書を整理します。

エージェントに権限を渡す場所は、実行時の確認ダイアログではなく、鍵そのものの形です。 今週、別々に見える三つの話がその一点に収束しました。AWS Japan の icoxfog417 氏による「AI エージェントの『認可疲れ』に効く処方箋」、 Retty の pikatenor 氏による「NO MORE $OPENAI_API_KEY」、 そして Gemini API が無制限 API キーのリクエストを拒否するという方針。 三つを一枚の表に並べると、残る結論はこれ一つです。鍵の形は三つの要素で決まります—— 短期(長期キーを配らず、数分のトークンに交換する)、スコープ(エンドポイント・操作・モデルを 鍵の中に書く)、上限(鍵ごとの予算とレート)。言い換えると、有効期限・権限範囲・予算上限が キーの属性として最初から付いている状態です。以下、三つの一次情報を順に読み、最後に その設計の請求書を書きます。
今週の三つの出来事
| 出来事 | 何が変わったか | 一次情報 |
|---|---|---|
| AWS Japan が「認可疲れ」の処方箋を公開 | エージェントの認可要求を、実行時のダイアログから一度の認証+トークン交換(RFC 8693)へ | Zenn 記事(2026-08-16) |
Retty が本番アプリから $OPENAI_API_KEY を撤去 | ECS タスクロール(IAM ロール)を STS が署名した JWT で証明し、OpenAI の短期トークンに交換 | Retty Tech Blog(2026-08-20) |
| Gemini API が無制限キーを拒否 | 無制限 standard キーを拒否(開始日 6/19 はフォーラム告知)、2026 年 9 月には standard キー全体を拒否し auth キーへ移行 | Google 公式ドキュメント、公式フォーラム告知 |
三つとも主語が違います。一つ目はエージェント基盤を作る側、二つ目はエージェントを使う アプリを作る側、三つ目はモデルを提供する側です。立場の異なる三者が同じ週に同じ方向へ 動いたことに意味があります。なお、同じ週の Zenn には ito 氏の「AI エージェントはなぜテストを握り潰すのか」もあり、 エージェントは「完了」までの最短経路を選ぶ、と整理されています。権限の境界をプロンプトの お願いではなく環境の側に置くべき理由は、この一文で足ります。
認可疲れの正体——要求が飛ぶのは実行時
AWS Japan の記事が整理する流れは三段階です。(1) ユーザーが社内 IdP(ID プロバイダ。Google や
Entra ID のような認証基盤)で認証し、エージェントが id_token を受け取る。(2) エージェントが
ツール(MCP サーバー経由の外部サービス)ごとに認可をユーザーへ求める。
(3) 認可済みのツールを代理実行する。問題は (2) の発生タイミングで、認可要求はツールを
実行しようとした瞬間にしか飛びません。「仕事を任せたと思ったら認可待ちで止まっていた」
という記事の表現は、エージェントを運用したことがある人なら身に覚えがあるはずです。
記事の処方箋は、ダイアログを減らすことではなく、(2) を (1) の結果から機械的に導くことです。
IdP が発行した id_token(「誰が認証したか」の証明)を外部サービスの認可サーバーに提示し、
そのサービス宛の access_token(「何をしてよいか」の許可)に交換する。RFC 8693 のトークン交換、その中でも「ユーザーの代理として」の
用法を OBO(On-Behalf-Of)と呼びます。交換後のトークンには、元の id_token になかった
二つのクレームが入ります。
| クレーム / 応答値 | 値 | 意味 |
|---|---|---|
scope | order:read order:write | このトークンで許される操作の範囲 |
act.sub | エージェントの client_id | 誰が代理で取得したか |
expires_in | 600 | 有効期間は 10 分(記事の実装例) |
つまり、権限の範囲と代理実行者のアイデンティティが、鍵の中に書かれた状態でエージェントに渡ります。 スコープが足りない操作は、ダイアログではなく 403 で止まります。

ここまでが処方箋の明るい面で、記事はコストも書いています。接続先の認可サーバーが
urn:ietf:params:oauth:grant-type:token-exchange を受け付ける必要があり、著者の見立てでは
執筆時点で大半が未対応です。記事の AWS 実装でも、既存の Cognito にはグラント種別を追加できない
ため、交換エンドポイント(/oauth2/token)を Lambda で新設しています。新規に書くのは
「交換リクエストの受付」と「自前の署名鍵でのトークン発行」の二つで、JWT の検証とユーザー権限の
解決は既存 SSO の流用です。「認可サーバーを一つ足す」が、このアプローチの最低限のコストになります。
鍵そのものを配らない——300 秒の IAM ロール証明を短期トークンに
Retty の記事は、同じ発想をモデル提供者との間で実践したものです。図 2 の順に三段階で読めます。

第一に、OpenAI API を呼ぶ ECS 上のアプリは $OPENAI_API_KEY を持たず、IAM ロールだけを持ちます。
第二に、AWS STS(一時認証情報を発行するサービス)がそのロールを証明する短命の JWT(署名付きの
トークン)を発行します。この機能が IAM の Outbound Identity Federation(OIF)です。第三に、
OpenAI の Workload Identity Federation(WIF)がその JWT を検証し、短期アクセストークンに
交換します。
数字を拾います。STS に発行させる JWT の有効期間は、IAM ポリシーの条件で 300 秒以下に
固定されています。300 は Retty の恣意的な値ではなく、STS の GetWebIdentityToken の
既定値
(指定可能範囲は 60〜3600 秒)であり、OpenAI の AWS 向け公式ガイドの例も同じ 300 秒です。
condition {
test = "ForAllValues:StringEquals"
variable = "sts:IdentityTokenAudience"
values = ["https://api.openai.com/v1"]
}
condition {
test = "NumericLessThanEquals"
variable = "sts:DurationSeconds"
values = ["300"]
}OpenAI 側はこの JWT を受け取り、iss・aud・sub(発行者・宛先・主体)の三つと Service
Account ID とが、事前登録済みのマッピングに一致するかを検証してから短期トークンを発行します。交換リクエストは、OpenAI の
API リファレンスに
ある通り RFC 8693 の形で、エンドポイントは auth.openai.com です。
curl https://auth.openai.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
"subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
"subject_token": "<STS が発行した JWT>",
"identity_provider_id": "idp_xxxxxxxx",
"service_account_id": "user-XXXXXXXX"
}'発行されるトークンの実効寿命は、上限の 3600 秒ではなく外部 JWT の残り時間で決まります。
OpenAI のリファレンスが「アクセストークンは最長 1 時間で失効し、交換に使った外部トークンより
長生きしない」と明記しているためで、STS の JWT を 300 秒に絞った構成では 300 秒側に引っ張られる
と読むのが安全です(筆者は未検証)。Retty の記事の脚注にある「デフォルトでは 3600 秒の
expires_in」はリファレンスのレスポンス例とも一致しており、上限の値として正しい。上限と実効値の
違いです。Retty の SDK は「渡した JWT と交換したアクセストークンのどちらか長い方の有効期限が切れた
タイミング」で再取得する、と記事にあります。どちらにせよ、鍵は「配る」ものから「数分ごとに
取り直す」ものに変わっています。
AWS Japan の記事が社内システム向けに自作した交換エンドポイントを、OpenAI は自社 API の 入口として提供している、と読めば二つの記事はつながります。そしてマッピング画面には、 この記事の主題にとって重要な欄がもう一つあります。

Permissions です。OpenAI のガイドでは、
マッピング単位で API 権限を付け、発行されるトークンをその範囲に縮小できる、とあります
(マッピングに権限を書かなければ Service Account の権限がそのまま乗る)。アイデンティティの
交換で「短期」を、マッピングの権限で「スコープ」を、鍵の形に入れているわけです。なお、リクエスト
本体に scope を書いても権限は付きません——リファレンスに「scope value in the request body
doesn’t grant access」とある通り、範囲を決めるのはマッピング側だけです。
対応範囲は二層で読む必要があります。プラットフォームとして受け付ける IdP は、
公式ガイドに載る
7 種——Kubernetes、AWS、Microsoft Azure、Google Cloud、Oracle Cloud Infrastructure、GitHub Actions、
SPIFFE(JWT-SVID)——と X.509 証明書(ベータ)で、載っていない OIDC 発行者は「contact us」扱いです。
一方 SDK に同梱された SubjectTokenProvider は、Retty の記事によれば執筆時点の openai-java
4.51.0 で Kubernetes / Azure / GCP の三つだけで、AWS OIF 向けは自作になっています。
コストも記事に書いてあります。自作した STS 呼び出しに加え、トークン交換レスポンスの scope が
既存の Jackson 設定で解析できず、FAIL_ON_UNKNOWN_PROPERTIES を無効にして回避しています。
新しい認証方式の初期費用は、たいてい SDK の穴として請求されます。
無制限キーは受け付けない——提供者側が鍵の形を強制し始めた
三つ目は方針の話です。Google の公式ドキュメントによれば、Gemini API は standard キーと authorization(auth)キーの二種類を持ち、後者へ移行中です。要点を原文の順に並べます。
- standard キーはリクエストを課金・クォータのために Google Cloud プロジェクトへ 紐付けるだけで、呼び出し元を識別しない
- auth キーはサービスアカウントに直接束縛され、リクエストはそのサービスアカウントの権限で 処理される。既定で Gemini API に制限され、漏洩が検知されたキーは速やかに停止される
- AI Studio で新規作成するキーは、すべて auth キーになる
- 無制限の standard キーは拒否。明示的な制限が付いた standard キーは引き続き動く。開始日が 2026-06-19 であることは、ドキュメント本文ではなく公式フォーラムの告知(2026-06-24 転載)による
- 2026-05-07 以降、長期間未使用の無制限キーはブロックされる
- 2026 年 9 月、standard キー全体が拒否対象になり、auth キーへの移行が必須になる

ここで起きているのは、利用者が善意で鍵を制限するのを待つのをやめ、形のない鍵を提供者が 受け付けなくするという転換です。AWS Japan と Retty が「鍵に形を与える」手順を書いた週に、 Google は「形のない鍵は捨てる」を実行に移していました。
三点セット——三つの一次情報を一枚の表に

三つの出来事を同じ軸で並べます。評価軸は「漏れたときの影響範囲(blast radius)」「ローテーション の手間」「使い過ぎの上限」の三つです。
| 鍵の形 | 漏洩時の影響範囲 | ローテーション | 使い過ぎの上限 | 今週の該当例 |
|---|---|---|---|---|
| 長期 API キー(無制限) | プロジェクト全体、検知まで無期限 | 人手、デプロイを伴う | 請求書で気づく | Gemini が 6/19 に拒否した形 |
| 制限付き standard キー | 制限した API の範囲内、ただし呼び出し元を識別しない | 依然として人手 | プロジェクト単位のクォータ | Gemini で 2026 年 9 月まで動く形 |
| auth キー(サービスアカウント束縛) | 束縛先サービスアカウントの権限内、漏洩検知で速やかに停止 | 依然として人手 | プロジェクト単位のクォータ | Gemini が 9 月以降に唯一残す形 |
| フェデレーション短期トークン | 最長 1 時間、外部トークン次第で数分、しかも IAM ロール等に束縛 | 自動で毎回更新 | マッピング権限で範囲は絞れるが金額上限は別の仕組み | Retty の WIF、AWS Japan の OBO |
最終行の「使い過ぎの上限」列にある ⚠ が、この記事で一番言いたい場所です。短期とスコープは、今週の三つの一次情報で
すでに実装と方針の両方が揃いました。上限だけは、どの記事にも主役として出てきません。
OBO の scope は「何をしてよいか」であって「いくらまでか」ではなく、OpenAI のマッピング
権限も同様です。LLM の API は一回の呼び出しで数万トークンを消費し、エージェントはそれを
ループで回します。鍵の形に「いくらまで」が入っていない限り、漏洩しなくても自分の
エージェントの暴走で請求が走ります。リトライの無限ループは、筆者の経験では漏洩より
先に来ます。
請求書——本番に持ち込む費用
三点セットを本番に持ち込む費用を、先に並べておきます。
- 認可サーバー側の対応。OBO を受け付ける認可サーバーは、AWS Japan の記事の見立てで 大半が未対応。自社サービスなら交換エンドポイントを一つ足す(記事では Lambda 一本)、 他社サービスなら相手が対応するまで待つ、の二択です。
- SDK の穴。Retty の記事が示した通り、提供者の公式 SDK でも IdP によっては
SubjectTokenProviderを自作する必要があり、レスポンスの解析で足を取られます。 公式ガイドが「サポート済み」と書く IdP 以外は、自作分の保守が毎バージョン付いてきます。 - 時計と有効期限のデバッグ。外部 JWT とアクセストークンという二つの有効期限が走る構成では、
障害の切り分けに「どちらが切れたか」が必ず入ります。自作クライアントではその再取得ロジックを
自分で書くことになります。細かい罠も一つ:STS の
GetWebIdentityTokenはグローバル エンドポイントでは使えず、リージョナルエンドポイント必須です。 - ローカル開発の抜け道。STS もクラウドのメタデータサービスも無い開発機では、結局どこかに 長期キーが残りがちです。 ここを放置すると、本番だけ三点セット、開発機は無制限キー、という一番漏れやすい形になります。
- 上限の別建て。三点セットの表で述べた通り、金額とレートの上限は認可の仕組みの外側で 持つ必要があり、鍵単位の予算を数えるコンポーネントが一つ増えます。プロバイダ側のプロジェクト 単位の予算アラートは今日使える代替ですが、粒度は「鍵ごと」ではなく「プロジェクトごと」です。
主要なモデル提供経路について、長期キーを使わずに呼べる経路を公式ドキュメントで確認できた範囲で 表にしておきます。載っていない提供者は未確認です。
| 提供経路 | 長期キー無しの経路 | 状態 |
|---|---|---|
| OpenAI API | Workload Identity Federation(OIDC JWT → 短期トークン、公式ガイド) | 提供中、7 種の IdP + X.509 ベータ |
| Gemini API(AI Studio) | auth キー(サービスアカウント束縛、漏洩検知で停止、公式) | 長期キーだがアイデンティティ付き。standard キーは 9 月で終了 |
| Azure OpenAI | Microsoft Entra ID / マネージド ID(DefaultAzureCredential、公式) | 提供中。短期トークン、秘密の保管なし |
| Amazon Bedrock | IAM 認証(SigV4)が既定。API キーは短期(最長 12 時間、IAM 主体の権限を継承)と長期の二種、公式は長期を「探索用途のみ」と明記 | 提供中。bedrock:CallWithBearerToken でキー種別ごとに拒否も可能 |
| Vertex AI | Application Default Credentials(サービスアカウント / Workload Identity Federation、公式) | 提供中。API キーも別途提供されるが、その制限の詳細は筆者未確認 |
ゲートウェイ側から見ると
LLM ゲートウェイは、この三点セットを実装する場所として都合がいい位置にいます。アプリと モデル提供者の間に立ち、鍵の発行者であり、同時にトークンを数える課金の場所でもあるからです。 私たち(pirouter のゲートウェイ)の場合、利用者に発行する API キーは設計上は、スコープ (どのモデル・どのエンドポイントを許すか)と上限(キーごとの予算とレート)を鍵の属性として持ち、 利用者側が持つ OIDC JWT を短期トークンに交換する入口も、上で見た OpenAI の WIF と同じ RFC 8693 の形に寄せる方針です。ゲートウェイ自身が上流プロバイダに対して持つ鍵についても、 正直に書いておきます。集約した分だけ漏洩時の影響範囲は大きく、だからこそ上流側に長期キー無しの 経路(上の表)があるものはそれを使い、無いものは長期キーを一か所に閉じ込めてローテーションと 監査の対象をそこだけにする、という設計です。今日ここで「対応している」とは書きません。書けるのは、 今週の三つの一次情報を読んだ後で、この三点を鍵の形から外す理由が見当たらなかった、ということだけです。
月曜にやる三つ
- 自社の認可サーバーの
/.well-known/oauth-authorization-server(Entra ID のように/.well-known/openid-configurationしか出さない IdP もあるので両方)を開き、grant_types_supportedにtoken-exchangeがあるか見る。無ければ、AWS Japan の記事の要件表で 「新規」になる行を数える。主要 IdP の対応状況は、筆者は今週確認できていません。 - 上の提供経路の表を自社の一覧に広げる。経路が無い提供者は、そのキーの制限とローテーション周期を 今の値で記録しておく。
- 鍵ごとの月額上限を、どのコンポーネントが数えているかを一行で書く。書けなければ、三点セットの 三つ目はまだ無い、ということです。