独自のID プロバイダーでエンドユーザーを認証する authentication
デフォルトでは、アプリ内のすべてのアクションは公開されています。 MCP サーバーのURLを持つLLM プラットフォームは、これらのアクションを呼び出すことができ、ハンドラーはエンドユーザーを識別できません。
アクションで、どのエンドユーザーが要求しているのか(注文、使用権限、アカウントの詳細など)を確認する必要がある場合は、認証をオンにします。 LLM プラットフォームは、your ID プロバイダー(IdP)でユーザーに署名し、結果として得られるアクセストークンを呼び出しごとに送信し、ハンドラーは検証済みのIDを受信します。
このガイドでは、 ID プロバイダーを接続し、ログインが必要なアクションを選択する方法について説明します。 ハンドラーで検証済みのIDを使用して、アプリをデプロイし、サインインと保護されたアクションをテストします。
認証の設定は高度なタスクです。 インフラストラクチャの設定、 アクションの作成、 アプリのデプロイ を最初に実行します。
仕組み
独自のID プロバイダーを利用できます。 デプロイされたアプリは、OAuth 2.1 リソースサーバーのみです。認証サーバーが発行したトークンを検証します。 トークンは発行されず、Adobeはクライアント IDまたはクライアント秘密鍵を格納しません。
┌── Your identity provider ───────────────────────────────────────────────┐
│ Authorization server — you own it │
│ Issues access tokens, holds the user directory, defines the scopes │
└─────────────────────────────────────────────────────────────────────────┘
▲ 2 user signs in, platform gets an access token
│ │
│ 1 platform discovers your │ 3 every tools/call carries
│ authorization server from │ Authorization: Bearer <token>
│ your app's metadata ▼
┌── LLM platform (ChatGPT, Claude, …) ────────────────────────────────────┐
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌── Your LLM App on Adobe I/O Runtime ────────────────────────────────────┐
│ Resource server — verifies the token's signature, issuer, audience, │
│ and expiry, then enforces the auth mode you set for each action │
│ │
│ Your handler reads the verified identity from its second argument │
└─────────────────────────────────────────────────────────────────────────┘
環境 ごとに認証 を設定します。 ステージと 実稼動 には、独立した設定が含まれています。 実稼動環境で認証を有効にする前に、開発IdP テナントに対する設定を確認してください。
始める前に
- 非対称アルゴリズムで署名されたJWT アクセストークンを発行するOAuth 2.1またはOpenID Connect ID プロバイダー。 不透明なトークンとHMAC署名済みトークンはサポートされていません。 トークン要件を参照してください。
- APIとクライアントを登録するためのID プロバイダーへの管理者アクセス権。
- 設定している環境にアプリを少なくとも1回デプロイします。 デプロイされたMCP サーバーのURLは、トークンのスコープを設定する必要がある値です。
リソース IDをコピー
アプリの リソース識別子 はMCP サーバーのURLです。 アプリに対してID プロバイダーが発行するすべてのアクセストークンには、そのURLをオーディエンスとして正確に名前を付ける必要があります。 このオーディエンスバインディングは、別のサービスに対して発行されたトークンの使用を防ぎます。
- アプリの詳細ページを開きます。
- アプリのテストまでスクロールします。
- 設定中の環境で、「URLをコピー」を選択します。
次の手順で、ID プロバイダー設定のコピーしたMCP サーバーのURLを保持します。 URLを再入力せずに貼り付けます。 オーディエンスチェックには、パスを含む正確な文字列一致が必要です。 1文字の違いがあると、すべてのトークンの検証が失敗します。
ID プロバイダーの設定
手順はプロバイダーによって異なります。 次の4つの項目を設定します。
- アプリをAPI (リソース)として登録します。 識別子(プロバイダーがトークンの
aud要求に入力する値)を、コピーされたMCP サーバーURLに設定します。 プロバイダーは通常、このフィールドに 識別子 または オーディエンス というラベルを付けます。 別のサービスに対して発行されたトークンの使用を防ぐには、apiなどの一般的な値ではなく、アプリに固有の識別子を使用します。 - アクションを保護するスコープを定義します(例:
orders:readまたはprofile:read)。 意味のある権限ごとに1つの範囲を使用して、各アクションが必要なアクセスのみを要求するようにします。 - PKCEをサポートします。 LLM プラットフォームは、すべての認証リクエストに
code_challenge_method=S256を含むcode_challengeを送信するので、認証サーバーはS256 PKCEをサポートし、そのメタデータで"code_challenge_methods_supported": ["S256"]をアドバタイズする必要があります。 - LLM プラットフォームがOAuth クライアントを識別する方法を選択します。 プロバイダーがプラットフォームの要件、動的クライアント登録(DCR)、または事前登録済みのOAuth クライアントをサポートしている場合は、クライアント ID メタデータ ドキュメント(CIMD)を使用します。 選択したメソッドが必要な場合にのみ、クライアント IDとシークレットを指定します。 Claudeのホストされたサーフェス
https://claude.ai/api/mcp/auth_callbackについて、プラットフォームによって文書化または表示された正確なリダイレクト URIを登録します。 ChatGPTは、プロバイダーの広告付き機能に応じて、安定したコールバックまたはコネクタ固有のコールバックを使用する可能性があるので、推測ではなく、表示されたURIをコピーします。 現在のChatGPT認証ドキュメント および クラウド認証ドキュメント を参照してください。
認証を有効にする
-
左側のナビゲーションで「設定」を選択し、「認証」タブを開きます。
-
Workspaceで、ステージまたは 実稼動 を選択します。
-
認証を有効にするをオンにします。
-
コア設定で、次のように入力します。
- Issuer —ID プロバイダーのHTTPS発行者URL。これは、各トークンの
iss要求に入力される値でもあります。 プラットフォームはこのURLを必要とし、イシュアをLLM クライアント発見用のアプリの認証サーバーとして公開します。 各アプリは1つのID プロバイダーをサポートしています。 - スコープがサポートされています – このアプリのアクションに必要なすべてのスコープが許可されます。 ID プロバイダーで定義したスコープをミラーリングします。
- Issuer —ID プロバイダーのHTTPS発行者URL。これは、各トークンの
-
詳細設定はオプションです。 署名キーが認証サーバーのメタデータで通知されている場所にない場合にのみ JWKS URI を設定します。そうでない場合は、アプリが自動的にそれらを検出します。
-
「保存」を選択します。
フィールドの要件については、認証設定を参照してください。
各アクションの認証モードを選択
認証を有効にするを有効にすると、現在 なし に設定されているすべてのアクションが 必須 に変更されます。 アクションごとの設定で、その割り当てを確認し、各アクションに必要なモードを設定します。
必須または オプション に既に設定されているアクションは、既存のモードを維持します。
必須またはオプション アクションの場合は、必要な スコープ を追加します。 すべてのスコープは既に サポートされているスコープ に表示されている必要があるため、アプリは必要な各権限をLLM プラットフォームに通知します。 範囲の不一致が解決されるまで、プラットフォームは保存をブロックします。
サポートされている 範囲 は、使用可能な範囲を制御します。 そのリストからスコープを削除すると、スコープを必要とするすべてのアクションからスコープがすぐに削除されます。 アクションにスコープを割り当てる前に、各スコープをリストに追加します。
すべてのアクションに対して認証を必要とするを選択すると、なしのアクションが 必須 に変更されますが、既に オプション に設定されているアクションは保持されます。 すべてのアクションに対してログインを要求するには、残りの オプション 行を個別に 必須 に変更します。 チェックボックスをオフにすると、すべてのアクションが None に戻ります。
完了したら、保存を選択します。 認証モードとスコープの変更は、アプリレベルの設定とともに保存されます。
ChatGPTは、1つのアプリ内で混合認証モードをサポートし、各アクションのモードを個別に適用します。 公開アクションではログインを求めるメッセージは表示されません。保護されたアクションでは、必要に応じてプロンプトが表示されます。
Claudeは、遅延認証を通じて混在アプリもサポートしています。 コネクタのセットアップ中に 必要に応じてログイン を選択すると、パブリックアクションは匿名で使用でき、必須 アクションが呼び出されたときにプラットフォームがログインを要求します。 アクションがすべて 必須 のアプリは、使用する前にログインする必要があります。 必須アクションとサインインを要求するオプションのハンドラーの違いについては、LLM プラットフォームの動作を参照してください。
変更をデプロイ
認証の変更は、このアプリの次回のデプロイに反映されます。 設定した環境にアプリを再び デプロイします。 アプリのデプロイ を参照してください。
MCP サーバーのURLは変更されません。 接続のメタデータを更新し、認証設定がアプリの新しい設定と一致することを確認します。 プラットフォームの認証方法が変更されたときに、接続を再接続または再作成する必要がある場合があります。
ハンドラーでIDを読み取る
確認されたIDは、アクションの認証モードに関係なく、発信者が有効なトークンを送信するたびに、2番目の引数としてハンドラーに到達します。 オプション アクションは、そのIDを使用して、利用可能な場合に結果をパーソナライズし、そうでない場合は匿名の結果を返すことができます。
getAuthenticatedUserを使用して、サインイン ユーザーを読み取ります:
const { getAuthenticatedUser } = require('@adobe/llm-apps-runtime');
module.exports = async ({ orderId }, extra) => {
const userId = getAuthenticatedUser(extra);
if (!userId) {
return { content: [{ type: 'text', text: 'Sign in to see your orders.' }] };
}
const order = await fetchOrderForUser(userId, orderId);
return {
content: [{ type: 'text', text: `Order ${order.id} is ${order.status}.` }],
structuredContent: order
};
};
ランタイムはトークンを検証します。 Required アクションの場合、リストされたスコープを持つ有効なトークンを欠くすべての呼び出しをブロックします。 ハンドラーは、許可された呼び出し元に対してのみ実行されます。 hasScopeを使用して、権限に基づいてハンドラーの動作を選択します(例:オプション アクション)。
会話中にログインをリクエストするには、ハンドラーからextra.challengeAuth()を返します。 ヘルパーは、オプションのアクションでのみ使用できます。
module.exports = async ({ signIn }, extra) => {
if (signIn && !extra.authInfo) {
return extra.challengeAuth({
error: 'invalid_token',
errorDescription: 'Sign in to see member pricing.'
});
}
return {
content: [{
type: 'text',
text: extra.authInfo ? await memberDeals() : await publicDeals()
}]
};
};
この例のsignInなどの明示的な入力パラメーターを使用して、認証を要求するタイミングを決定します。 その決定をユーザーの言葉遣いから推測しないでください。
報告された条件に一致するようにerrorを設定します。 呼び出し元に有効なセッションがなく、上記の例のようにログインが必要な場合は、invalid_tokenを使用します。 呼び出し元がサインインしているが、トークンに必要な範囲が不足している場合はinsufficient_scopeを使用します。 各LLM プラットフォームは、プロンプトの文言とエラーコードへの対応方法を選択します。 条件を正確に記述したコードを送信します。
この例では!extra.authInfo チェックで示されているように、必要なIDが見つからない場合にのみ認証を要求します。 ログインしても、無条件の課題は解決されません。ハンドラーは、呼び出しごとに認証を再度要求します。
extra.challengeAuth()は、ChatGPTに対するツール結果チャレンジを返します。 代わりに、Claudeは、ハンドラーを実行する前にHTTP認証チャレンジを必要とします。 サポートされているプラットフォーム間でログインが必要な操作の場合は、必須 アクションを使用します。 必要に応じて、パブリックエクスペリエンス用に個別のNone アクションを保持します。IDはサーバーサイドにしておきます。 ウィジェットに必要なデータのみをstructuredContentに渡します。 structuredContentにアクセストークンを絶対に含めないでください。 生成ハンドラーのカスタマイズ を参照してください。
完全な契約については、 ハンドラー認証APIを参照してください。
保護されたアプリのテスト
既存のプラグインまたはコネクタは、デプロイメント後に更新された設定を使用します。 新しい接続を作成するには、プラットフォームの手順に従います。
ChatGPT
新規プラグイン ダイアログで、認証を設定して、アプリのアクションの設定方法と一致させます。
オプション アクションは常に匿名呼び出しを受け付けるので、それを含むアプリは完全にゲートされることはありません。すべてのアクションが オプション に設定されている場合でも、混在を選択します。 未認証の発信者を拒否するのは 必須 のみです。
ダイアログの残りの部分については、ChatGPT プラグインのテスト を参照してください。
Claude
カスタムコネクタを追加し、認証設定を確認します。 公開と保護が混在するアプリの場合は、必要に応じてログインを選択します。 コネクタを使用する前にログインをリクエストするには、今すぐログインを選択します。 ダイアログはアカウントまたは組織によって異なります。Claude コネクタのテスト を参照してください。
確認
- プラットフォームは、独自のID プロバイダーのサインインページにリダイレクトします。
- 保護されたアクションは、ログイン後にユーザー固有のデータを返します。
- ログアウトすると、保護されたアクションでログインを求められます。
- 混在アプリでは、Noneに設定されたアクションは、ログインせずに応答します。 Claudeで、必要に応じてログインして公開アクションを確認します。
- ログイン後、保護されたアクションを再試行し、ランタイムが期待される権限を適用することを確認します。
ログインが開始されない場合、またはトークンが拒否された場合は、 トラブルシューティング を参照してください。
セキュリティガイダンス
- 各行動に必要な範囲を最も広げる。 あらゆる行動において、ひとつの広い範囲を再利用してはいけません。
- ID プロバイダーとLLM プラットフォームのコネクタ設定で、クライアントを秘密にしておきます。 メタデータ、ハンドラーコード、ウィジェット、JavaScript、ソースコントロールなどを決して実行しない。
- トークン要求を外部システムからの入力として扱います。 クエリでこれらの値を使用する前に、
authInfo.extraの値を検証します。 - 認証を行います。 有効なトークンは、特定のレコードを読み取る権限ではなく、ユーザーのIDを証明します。 データを返す前に、ハンドラーの所有権を確認してください。
- トークン、完全な要求セット、ユーザーIDはログに記録しないでください。
- 安全なエラーを返します。 アップストリーム ID プロバイダーの応答またはスタックトレースをユーザーに表示しないでください。
- 実稼動環境で認証を有効にする前に、実稼動以外のID プロバイダーのテナントに対して ステージ を設定して検証します。
次の手順
- 認証参照 — フィールド、トークン要件、プラットフォーム動作。
- 生成されたハンドラーをカスタマイズ – 保護されたアップストリーム APIをハンドラーから呼び出します。
- アプリをデプロイ 。