AIエージェント認証、APIキーを減らす設計

AIエージェント認証、APIキーを減らす設計

AIエージェントが外部サービスを操作するたび、長期間使えるAPIキーを直接渡していないでしょうか。

秘密を環境変数へ移すだけでも、ソースコードへの直書きは防げます。しかし、漏れた資格情報が長期間使える問題までは解決しません。

先に結論

エージェント認証は、次の3層へ分けると被害範囲を小さくできます。

1. 秘密鍵は鍵管理サービスから外へ出さない

2. 秘密鍵で有効期限の短いJWTを署名する

3. JWTと交換した短命アクセストークンだけをエージェントへ渡す

Private Key JWTは、すべてのAPIキーを自動的に置き換える仕組みではありません。接続先の認可サーバーが対応していることが前提です。それでも、対応サービスでは「同じ共有シークレットを毎回送る」設計から離れる選択肢になります。

今回、実際に確認したこと

現在のWordPress公開自動化を確認すると、サイトURL、APIユーザー、アプリケーションパスワードを環境変数から読み込む構成でした。秘密値そのものを原稿やコードへ書かない点は守られています。

一方、WordPressのアプリケーションパスワードは、失効させるまで使える長期資格情報です。環境変数で安全に読み込んでも、実行中のエージェントが必要以上の期間・権限で保持すれば、漏えい時の影響は残ります。

今回の記事では秘密値を表示せず、変数名と読み込み方法だけを確認しました。Private Key JWTへの移行を実装済みとはせず、どの接続先から移行を検討すべきかを整理します。

Private Key JWTの流れ

RFC 7523は、JWTをOAuth 2.0のクライアント認証に使う方法を定義しています。大まかな流れは次のとおりです。

1. クライアントが発行者、対象、宛先、有効期限を含むJWTを作る

2. 秘密鍵でJWTへ署名する

3. 認可サーバーのトークンエンドポイントへJWTを送る

4. 認可サーバーが公開鍵で署名と内容を検証する

5. 成功した場合だけ短命アクセストークンを発行する

秘密鍵そのものは認可サーバーへ送りません。共有シークレットを要求ごとに送る方式とは、ここが大きく異なります。

AWSが公開したAmazon Bedrock AgentCore Identityの手順では、AWS KMSの署名鍵を作成し、公開鍵をIDプロバイダーへ登録し、エージェントのアクセスをCloudTrailで確認する流れが紹介されています。

JWTで必ず確認する5項目

JWTは署名されていれば十分ではありません。RFC 7523では、クライアント認証用JWTの検証に必要な内容が示されています。

発行者と主体

クライアント認証では、発行者と主体がどのクライアントを表すかを接続先と合意します。別のクライアントIDを受け入れないことをテストします。

宛先

audには、JWTを受け取る認可サーバーを指定します。別環境や別テナント向けに作られたJWTを誤って受け入れないための境界です。

有効期限

expで利用可能な時間を短くします。有効期限を長くしすぎると、短命資格情報へ変える意味が薄れます。時計ずれをどこまで許容するかも決めます。

一意なID

jtiを使うと、同じJWTの再利用を検出しやすくなります。ただし、RFC 7523ではリプレイ防止を必須としていません。実装側で使用済みIDを保持するか、有効期限を十分短くする必要があります。

署名と鍵ID

認可サーバーは署名を検証し、無効なJWTを拒否します。鍵をローテーションするなら、kidと公開鍵の配布方法、旧鍵を受け入れる期間まで設計します。

KMSを使う理由

AWS KMSの非対称署名鍵では、秘密鍵を平文で取り出さずにSign APIで署名できます。公開鍵はGetPublicKeyで取得し、外部のIDプロバイダーへ登録できます。

ここで重要なのは、エージェントへ秘密鍵ファイルを配布しないことです。エージェントには署名APIを呼ぶ権限だけを与え、対象の鍵と操作をIAMで絞ります。

KMSを使えば自動的に安全になるわけではありません。kms:Signを広いリソースへ許可したり、任意の内容を署名できたりすれば、別の問題が生まれます。

どこから移行するか

すべての連携を一度に変える必要はありません。次の順番で優先度を付けます。

1. 本番データを変更できるエージェント

2. 請求、顧客情報、非公開コードへ触れる連携

3. 複数の自動処理で共有しているAPIキー

4. 失効や利用履歴をすぐ確認できない資格情報

5. 開発用と本番用で同じ秘密を使っている接続

読み取り専用の公開データ取得より、投稿、削除、課金へつながる操作を先に見直します。

導入前に行う5つの失敗テスト

正常系だけでは、認証境界を確認できません。少なくとも次を試します。

1. audを別のトークンエンドポイントへ変えると拒否される

2. expを過去にすると拒否される

3. 未登録の鍵で署名すると拒否される

4. kms:Sign権限を外すと署名できない

5. 同じjtiを再送したときの挙動を記録する

さらに、誰が、どの鍵で、いつ署名したかを監査ログで追えることを確認します。AWSのAgentCore Identityは、資格情報の保存とアクセスを分け、長期シークレットやリフレッシュトークンをエージェントへ直接見せない構成を説明しています。

現在のブログ自動化へ当てはめる

WordPress公開では、アプリケーションパスワードを環境変数から読む現在の方式をすぐ廃止することはできません。WordPress REST API側がPrivate Key JWTを標準の置き換えとして提供しているわけではないためです。

そこで、現状は次の対策を続けます。

  • 公開専用ユーザーを分ける
  • 必要最小限の権限だけ与える
  • 秘密値を原稿、ログ、公開HTMLへ出さない
  • 利用履歴を確認し、不要な資格情報を失効する
  • 投稿後に外部URLと内容を検証する

一方、OAuth 2.0対応の外部サービスやAgentCore経由のツール連携では、Private Key JWTと短命トークンを候補にします。接続先の対応状況を確認し、長期キーを減らせる場所から移行します。

認証情報をAIへ渡す前の境界は、Codexに秘密を渡さない3つの境界でも整理しています。AIエージェントの権限を広げる前に確認したい項目は、AI記事制作、最後に人が見る3項目の公開前監査とも共通します。

まとめ

AIエージェントの認証で減らしたいのは、コードへ書かれた秘密だけではありません。漏れた後も長く使える資格情報と、必要以上に広い権限です。

Private Key JWTを使える接続先では、秘密鍵を鍵管理サービス内に置き、短い有効期限のJWTを署名し、短命アクセストークンへ交換します。対応していない接続先では、専用ユーザー、最小権限、失効、監査を徹底します。

最初の一歩は、現在の自動化が使う資格情報を一覧化し、「有効期間」「権限」「失効方法」「利用履歴」の4列を埋めることです。

関連記事

著者情報

しろのあブログでは、AIエージェントを個人環境やブログ運用へ導入するときの権限、秘密情報、公開前監査を、公式仕様と実際に確認した運用状態に分けて整理しています。

出典

1. Authenticate with Private Key JWT using Amazon Bedrock AgentCore Identity / AWS

2. Manage credential providers with AgentCore Identity / AWS

3. RFC 7523: JSON Web Token Profile for OAuth 2.0 Client Authentication and Authorization Grants / IETF

4. AWS KMS Sign API / AWS

5. AWS KMS GetPublicKey API / AWS