AIエージェントは、従来のソフトウェアにはなかった一線を越えています。彼らはあなたのSlackを読み、メールを下書きし、コードを投入し、CRMを更新し、請求書を支払います。そのためには、特定の人に属するシステムへのキーが必要です。アプリケーションではありません。会社ではありません。人です。
それが、エージェントの文脈で「ユーザー別OAuth」が存在する唯一の理由であり、サイドプロジェクトと、Gmailアカウントを顧客が任せて信頼できるものとの違いです。
この記事では、AIエージェントにおけるユーザー別OAuthが意味すること、共有クレデンシャルがスケールすると崩壊する理由、登場しつつある標準がどのようなものか、そしてそれを扱うプラットフォームを選ぶ際に使うべき正確なチェックリストを分解して説明します。また、スタックを自分で組み立てる必要がないように、Composioがこれらの問題それぞれにどう取り組んでいるかも示します。
多くのチームが最初に始める方法にある問題
ほとんどのエージェントの試作は、環境変数に1つのAPIキーを置くことから始まります。これは、開発者1人・マシン1台・デモ1回であれば機能します。しかし、実際のユーザーが現れた瞬間に、モデルは壊れます。
APIキーはアクションの背後にいるユーザーではなく、呼び出しているアプリケーションを識別します。エージェントからの各リクエストは、下流のサービスからはすべて同じに見えます。コンセント(同意)の概念がなく、ユーザーごとのスコーピングもなく、全員を無効化せずに1人のアクセスだけを取り消す手段もなく、さらに「このアクションはSarahがエージェントに頼んだ結果として起きた」という監査ログもありません。
これはすぐに深刻なセキュリティ問題になります。エージェントのコードが誤って違うユーザー識別子を渡してしまったり、攻撃者がエージェントに「承認していないユーザーのデータを要求させる」ように仕向けたりしても、エージェントにはプロトコルレベルでの防御策がありません。これは典型的な「困惑した代理人(confused deputy)」問題であり、1タスクにつきツール呼び出しを何十回も連鎖する自律システムでは、規模が大きくなるほど最悪の形で拡大します。
Composio自身のAIエージェント基盤に関するガイドでは、これを「Authentication Wall(認証の壁)」にぶつかることと呼んでいます。つまり、有望な試作が有望でなくなる瞬間です。
ユーザー別OAuthが実際に解決するもの
ユーザー別OAuthはモデルを反転させます。エージェントが1つのマスター資格情報を保持するのではなく、各ユーザーが自分のアカウントに紐づくスコープ付きで取り消し可能なトークンをエージェントに付与します。エージェントは、そのユーザーのアイデンティティとして行動し、そのユーザーが承認した範囲内で、ユーザーが許可する限りにおいて活動します。
具体的に、これにより次が得られます:
明示的な同意。 ユーザーは、エージェントが何を要求しているかを確認し、承認します。推測によるアクセスはありません。
スコープ化された権限。 トークンは、フルのアカウント制御ではなく、特定のリソースに対する読み取り専用アクセスなどに制限できます。エージェントが読むだけでよいなら、それだけが付与されます。
有効期限の短さ。 アクセストークンは数分〜1時間で期限切れになります。リフレッシュトークンはローテーションされます。漏えいしたトークンは、永遠ではなく短い期間だけ危険です。
選択的な取り消し。 あるユーザーの付与(grant)を取り消しても、他のユーザー向けにエージェントが壊れることはありません。
監査ログ内でのアイデンティティ。 すべてのアクションが特定のユーザーに追跡できるため、SOC 2、HIPAA、ISO 27001が実際に要求しているものを満たします。
マルチテナントの隔離。 各ユーザーのトークンはそれぞれのバケットに保存され、保存時に暗号化されます。あるテナントのワークフローのバグが、別のテナントのデータを公開することはありません。
最後のポイントは、人々が考える以上に重要です。Composioのユーザーとセッションのモデルは、まさにこの考え方に基づいて作られています。ユーザーとはあなたのアプリ内の識別子であり、すべての接続はそのユーザーIDの下に存在し、接続はユーザー間で完全に隔離されます。同じエージェントのコードが、誰かが互いのデータに触れることなく、数千人のユーザーに対して動作できます。
実際に形作っている標準
プロトコル層は急速に進んでいます。知っておくべき重要なことが3つあります。
mandatory PKCEを伴うOAuth 2.1
OAuth 2.1は、OAuth 2.0の現在のベストプラクティスとしての統合版です。PKCE(Proof Key for Code Exchange)を必須にし、より古くて安全性の低いフローを削除します。PKCEがエージェントにとって特に重要なのは、多くのエージェントが、クライアントシークレットを確実に隠せない環境で動作するパブリッククライアントとして動くためです。PKCEは、フローの途中で攻撃者が認可コードを横取りすることを防ぎます。
評価しているプラットフォームがPKCEを強制していない場合、それは危険信号です。
MCP認可仕様
Model Context Protocol認可仕様は、2025年に標準としてOAuthを形式化しました。OAuth 2.1 + PKCEを必須とし、RFC 8414によるAuthorization Server Metadataのディスカバリ(発見)を要求し、RFC 7591によるDynamic Client Registrationをサポートします。2025年11月のアップデートではステップアップ認可が追加され、最初のトークンを過剰な権限で付与するのではなく、実際に操作が必要とする場合にのみクライアントが追加スコープを要求できるようになりました。
また、この仕様には対処すべき現実のセキュリティ危機もありました。2025年後半、Obsidian Securityのセキュリティ研究者が、複数の著名な組織のリモートMCPサーバーにおけるワンクリックアカウント乗っ取りの脆弱性を開示しました。根本原因は、なかでも多くのMCPサーバーが、上流のSaaSの認可サーバーと通信するために、単一の固定されたclient_idを使うOAuthプロキシとして実装されていたことです。どれかのユーザーがその共通のclient_idについて同意すると、SaaSの認可サーバーがその判断をキャッシュしていました。攻撃者は、その後MCP層の同意を自分で完了させ、細工した認可リンクを被害者に送信すればよくなります。上流サーバーは、過去に同じclient_idを見たことがあるため、同意プロンプトを完全にスキップしてしまうためです。認可コードは攻撃者のリダイレクトURIに発行されます。
解決策は、プロキシ層でのクライアントごとのアイデンティティと、厳格な同意の取り扱いです。ComposioのTool Routerは、各セッションに共有エンドポイントではなく、セキュアでユーザーがスコープされたMCP URLを付与することで、構造的にこの種の攻撃を回避します。
AIエージェント向けのIETF「On-Behalf-Of」ドラフト
稼働中のIETFドラフトとして、draft-oauth-ai-agents-on-behalf-of-userがあります。これはエージェントの委任のために、OAuthを特化して拡張します。requested_actorパラメータを追加し、同意画面にアプリだけでなくエージェントの身元を表示するようにし、さらにactor_tokenパラメータを追加して、許可コードを交換するときにエージェント自身が認証できるようにします。
その結果として得られるアクセス・トークンは、委任の全チェーンを文書化します。ユーザーがこのクライアントアプリケーションに委任し、そのアプリケーションがこの特定のエージェントに委任した、という流れです。このチェーンこそが、事後監査を可能にします。
このドラフトは2025年8月時点で改訂02ですが、まだ作業部会に採用されていません。しかし、プロトコル層がどこへ向かっているかは明確に示しています。同一ユーザーの代わりに、エージェントAがエージェントBを呼び出すようなマルチホップ委任は、仕様上なお未解決の課題です。
生産(本番)アーキテクチャ:チームが失敗するポイント
アクセス・トークンを取得することは簡単です。問題は本番規模で運用するところで、多くの自作OAuth実装がここで崩れます。うまくいかないことはだいたい5つあります。
トークンの保管。 トークンは保管時に暗号化し、テナントごとに分離し、決してログに記録せず、決してLLMの文脈(コンテキスト)に置かない必要があります。最後の点は自明ではなく、しかも重要です。プロンプトにリフレッシュ・トークンを入れると、プロンプトインジェクション攻撃によってそれが流出する可能性があるからです。使うべきパターンは、仲介された認証情報(brokered credentials)です。ここではLLMがトークンをまったく見ず、別のサービスが実際のAPI呼び出しを行います。
Composioのsecure infrastructure guideでは、このパターンを直接説明しています。LLMがComposioにアクションを依頼し、Composioが保存された認証情報を使って上流のAPIを呼び出し、トークンはモデルのコンテキストウィンドウに入ってきません。
リフレッシュの取り扱い。 リフレッシュ・トークンには先回り(プロアクティブ)な調整が必要です。401エラーを待ってから更新すると、競合状態が起き、リトライが連鎖して、バックグラウンドのジョブが不安定になります。Composioはリフレッシュを自動で処理し、複数回のリフレッシュ試行が失敗した後に限って接続をEXPIREDとしてマークします。これはauthentication docsに従っています。
スコープの規律。 Composioは各ツールキットに対して妥当なデフォルト・スコープを要求しますが、custom auth configsで上書きすることもできます。スコープを締めることで、何かがうまくいかなかった場合の影響範囲(ブラスト半径)を縮小できます。ほとんどのAPIは依然として粒度の粗いスコープしか提供していないため、規律を守っていてもエージェントは過剰に権限を持ちがちです。対策は、短いトークン寿命と、APIが対応している場合はツールごとのスコーピングです。
ブランド表示と同意画面。 ユーザーがOAuthの同意画面に到達したとき、「YourProductがあなたのGmailにアクセスしたい」といった文言ではなく「ComposioがあなたのGmailにアクセスしたい」と表示されるなら、コンバージョンは低下し、信頼も損なわれます。Composioのwhite-labeling supportにより、自社のOAuthアプリ認証情報を持ち込めるため、同意画面に自社のブランドを表示できます。プロトタイピングにはマネージド・アプリを使い、本番には自社の認証情報を使ってください。
ユーザーごとの複数アカウント。 ユーザーの中には、個人用のGmailと仕事用のGmailの両方を接続する人もいます。プラットフォームは、両者でユーザーIDを共有することを強制せずに、それをモデル化できる必要があります。Composioはこれを、ユーザーIDの下に重ねる形で「接続されたアカウントID」を使うことで対応しています。これにより、同じツールキットに対して1人のユーザーが複数のアカウントを持てます。これはusers and sessions guideで説明されています。
エージェント向け・ユーザー単位のOAuthプラットフォームで見るべき点
提供者(プロバイダ)を評価するなら、ここは譲れません:
- ユーザーごとのトークン分離(保管時暗号化と、テナント間の漏えいなし)
- すべてのOAuthフローに必須のPKCEを伴うOAuth 2.1
- クライアントに依存しない、自動かつ先回りのトークン更新
- 回転するリフレッシュ・トークンを備えた短寿命のアクセス・トークン
- 統合ごとに最小権限となるような粒度の細かいスコープ設定
- LLMが生のトークンを見ないようにする仲介された認証情報(brokered credentials)
- 他のユーザーに影響を与えずに行える、選択的なユーザー単位の失効
- コンプライアンスのための委任チェーンに関する監査証跡
- 本番での信頼のためのホワイトラベルOAuth同意画面
- 必要なときだけ新しいスコープを要求するためのステップアップ認可
- 同じアプリにおける個人アカウントと仕事アカウントのためのユーザーごとの複数アカウント
- MCPネイティブのデプロイ(任意のMCP対応クライアントが同じ認証レイヤーを使えるように)
- SOC 2 Type 2およびISO 27001への準拠(エンタープライズ顧客向けの最低条件)
- 主要なフレームワークにまたがるSDKサポート(LangChain, CrewAI, OpenAI Agents SDK, Claude Agent SDK, Mastra, Vercel AI SDK, LlamaIndex)
Composioは、今日このリストにあるすべての項目をカバーしています。500以上のツールキットをサポートし、ユーザー単位のトークンでOAuthをエンドツーエンド処理し、SOC 2 Type 2およびISO 27001に準拠しており、直接のSDKとしてもMCPサーバーとしても動作します。機能の全詳細は、AgentAuthプロダクトページと、比較ガイドにあります。
コードで見るとこうなる
Composioでのユーザー単位OAuthは、数行に圧縮できます。以下のパターンは、Composioのauthenticating tools guideでドキュメント化されている現行SDKに従っています。
まず、SDKをインストールしてAPIキーを設定します:
pip install composio
export COMPOSIO_API_KEY=your_api_key_here
特定のユーザーに対してOAuthフローを開始するには、ホストされたConnect Linkパターンを使います。これにより、ユーザーがブラウザで開いて認証を完了するためのリダイレクトURLが返されます:
from composio import Composio
composio = Composio(api_key="your_api_key")
# Composioダッシュボードの「AUTH CONFIG ID」を使います
auth_config_id = "your_auth_config_id"
返却形式: {"translated": "翻訳されたHTML"}# アプリケーション内の各ユーザーに対して一意の識別子を使用するuser_id = "user_1349_129_12"
connection_request = composio.connected_accounts.link(
user_id=user_id,
auth_config_id=auth_config_id,
callback_url="https://your-app.com/callback"
)
redirect_url = connection_request.redirect_url
print(f"アクセス先: {redirect_url} にアクセスしてアカウントを認証してください")
ユーザーがフローを完了すると、Composio はトークンを保存し、それらをそのユーザー ID に紐づけ、更新も自動的に処理します。エージェントのコードはトークンに直接触れることはありません。
特定のユーザーにスコープされたツールを取得するには、同じユーザー ID を渡します:
from composio import Composio
composio = Composio(api_key="your_api_key")
user_id = "user_1349_129_12"
# ツールは、このユーザーの接続済みアカウントに自動的にスコープされます
tools = composio.tools.get(user_id=user_id, toolkits=["GITHUB", "GMAIL"])
同じワークフローを 2 人のユーザーが実行しても、2 つの異なる認証情報セットが透過的に適用されます:
tools_user_1 = composio.tools.get(user_id="user_1", toolkits=["GITHUB"])
tools_user_2 = composio.tools.get(user_id="user_2", toolkits=["GITHUB"])
# エージェントが呼び出したときに、各ツールセットは
# 対応するユーザーの認証情報を使用します
これが、ユーザーごとの OAuth の本質です。認証レイヤーはプラットフォームに吸収され、エージェントのコードは、何千人に提供していても 1 人のユーザーと話しているかのように読み書きできます。
LLM フレームワークを使った完全に動作する例については、Composio のドキュメント内のフレームワーク別クイックスタートガイドをご覧ください。
The takeaway
ユーザーごとの OAuth は、後からエージェント製品に「後付け」できる機能ではありません。そもそも、あなたのエージェントが実在の顧客に提供できるかどうかを決める基盤です。共有 API キーでは、上限は 1 人のデモに留まります。ユーザーごとの OAuth は、多テナントの本番デプロイ、エンタープライズのコンプライアンス、そして顧客の受信トレイ、カレンダー、または収益パイプラインを扱うために必要な種類の信頼を開きます。
プロトコルレイヤーは今も進化しています。OAuth 2.1、MCP の認可仕様、そして IETF の on-behalf-of draft はすべて、同じ答えに収束しています。つまり、明示的なユーザー同意、スコープされた委任、監査されたトークンのライフサイクル、そしてユーザーごとの分離です。このモデルを今のうちに作り込めば、後でリトロフィットする必要はありません。
自分でそれを何か月もかけて作る代わりに、Composio から始めるか、完全なアーキテクチャについて auth-to-action ガイドを読んでください。プロトタイプから本番までの最短ルートは、すでにこの問題を解決済みのプラットフォームを使うことです。






