Microsoft Foundry のツールボックス認証によって、ツールがダウンストリーム サービスに対してどのように認証されるかが決まります。 認証設定はプロジェクト接続で構成され、エージェントは、エージェント コードに認証ロジックを実装せずに、匿名アクセス、共有資格情報、サービス ID、またはサインインユーザーの ID を使用できます。
この記事では、ツールボックス認証のしくみについて説明し、各ユーザーのアクセス許可とアクセス境界を維持しながら、プライベート MCP サーバーと Work IQ の OAuth ID パススルーを構成する方法について説明します。
ツールボックスは、接続の認証を一元化します。 認証は接続のプロパティであり、エージェント内のコードではありません。 ツールを接続すると、認証の種類を選択し、Foundry はサービス側でトークンの取得、交換、更新、挿入を処理します。 エージェント コードは、認証フローではなくビジネス ロジックに重点を置いたままになります。
ユーザーごとの認証が自分で構築するのが難しい理由
Entra で保護されたツールへのユーザー単位のアクセス制御を自分で実装すると、気づきにくい形で誤りを生みやすい、セキュリティ上重要な基盤処理を自ら担うことになります。
- ユーザーごとのトークン分離を自分で実装します。 ユーザーとテナントによってトークン キャッシュを正しくパーティション分割する必要があります。 キャッシュ キーが間違っていると、あるユーザーのダウンストリーム API アクセスが別のユーザーにサイレント モードで漏えいする可能性があります。これは、すべての機能テストに合格するバグです。
- リソースごとに、ユーザーごとの同意とライフサイクルを管理します。
AADSTS65001などの同意エラーを検出し、同意を通じてユーザーを送信し、期限切れのトークンを更新し、作成するすべてのエージェントで API ごとに 401/403 回の再試行を正しく処理する必要があります。 - ツールやエージェントに比例して増大する複雑さを吸収します。 新しいツールごとに、別のスコープ、トークン交換、キャッシュ エントリ、同意パス、再試行パス、ヘッダー パスが追加されます。 何百ものツールと何千ものエージェントにスケーリングすると、同じ脆弱な配管を何度も繰り返し再構築します。
すべてのツール呼び出しの 2 つの ID
押さえておくべきメンタルモデルはこうです。常に2つのアイデンティティが存在し、ユーザーごとの認証にまつわる難しさはすべて、それらを正しく保ち、互いに分離し、同時利用中のユーザー間で決して取り違えないようにすることにあります。
- エージェントとツールボックスの境界 (安定した境界)。 エージェントは、独自のエージェント ID を使用してプラットフォームに対して認証を行います。 この ID は 、ツールボックス自体へのアクセスをゲートします。内部の個々のツールにはアクセスできません。
- ツールからデータへの境界 (ユーザーごとの境界)。 実際のデータ呼び出しでは、Foundry は、サインインしているユーザーを表す資格情報をダウンストリーム サービスに提供します。 認証の種類に応じて、これらの資格情報は OAuth 承認フローまたは対象ユーザー固有のMicrosoft Entra アクセス トークンから取得されます。 ダウンストリーム サービスは、ユーザーがアクセスできるもののみを返し、ユーザーのアクセス許可と秘密度ラベルに従います。
ツールボックスが認証を処理する方法
ツールボックスは、認証の負担全体をエージェントから接続に移動します。
- 認証は、エージェントではなく、接続上に存在します。 ツールを接続するときに、認証の種類を 1 回選択します。 エージェント コードは認証不要のままです。
- Foundry はフロー全体を処理します。 Foundry は、ツールのニーズに応じて、API キーの格納と挿入、サービス ID の資格情報の取得、OAuth 承認の完了、または対象ユーザー固有のMicrosoft Entraアクセス トークンの提供を行います。 Foundry は、ユーザーごとの資格情報を他のユーザーから分離します。
- ビジネス ロジックを構築するだけです。 認証フローは、そもそもあなたが構築するものではありませんでした。
| DIY の負担 | ツールボックスが代わりに実行する内容 |
|---|---|
| ユーザーごとのトークンの分離 | Foundry は、呼び出し元ごとにトークンを自動的に分離します。 間違って取得するキャッシュ キーはありません。 |
| 同意とライフサイクルの処理 (ユーザーごと、リソースごと) | Foundry は、必要な同意が付与された後のトークンの取得と更新を含め、各ユーザーの同意フローとトークンのライフサイクルを管理します。 |
| ツールごとおよびチームごとに再実装された認証 | ツールと認証を使用してツールボックスを 1 回作成し、すべてのエージェントとランタイムで再利用します。 |
接続で認証の種類を設定する
認証の種類は、接続の作成時、ポータル、Azure Developer CLI を使用する場合、または REST API を使用して選択します。 エージェント コードに含まれることはありません。 各認証タイプによって、どのユーザーのID情報がツールに渡されるかが決まります。
authType |
誰の ID がツールに到達したか | これを次の目的に使用します。 |
|---|---|---|
none |
アノニマス | パブリック サーバー (たとえば、Microsoft Learn MCP サーバー)。 |
custom-keys |
格納されている API キーまたはヘッダー | キーベースの SaaS。 エージェントがシークレットを見ることはありません。 |
project-managed-identity |
プロジェクトのマネージド ID | ユーザー コンテキストのないサービス間呼び出し。 |
agentic-identity |
エージェント自身の ID | エージェントごとの監査と最小特権。 |
oauth2 |
OAuth 承認を完了したユーザー | Work IQ やパートナー MCP サーバー (Vercel など) を含む OAuth に準拠したサービス。 |
user-entra-token |
サインインしているMicrosoft Entraユーザー | ワークスペース専用の Fabric データ エージェント エンドポイントなど、対象ユーザー固有の Entra トークンを必要とする管理対象の Microsoft サービス。 |
oauth2とuser-entra-tokenはどちらもユーザーごとのアクセスをサポートしますが、資格情報の取得方法は異なります。
oauth2を使用すると、ユーザーは OAuth 承認フローを完了し、Foundry は結果の資格情報を格納して更新します。
user-entra-tokenでは、Foundry はダウンストリーム サービスに、サインインしているユーザーを表す対象ユーザー固有のMicrosoft Entra アクセス トークンを提供します。 サービスに必要な認証の種類を使用します。
認証の種類ごとに接続を構成する
各接続を azd ai connection createに登録します。 コマンド図形は常に同じです。フラグは認証の種類によって異なります。 MCP および A2A サーバーに --kind remote-tool を使用します。
azd ai connection create my-mcp-conn \
--kind remote-tool \
--target https://public-mcp.example.com/mcp \
--auth-type none
チュートリアル: OAuth ID パススルー
この例では、プライベート注文 MCP サーバーと Work IQ という 2 つのMicrosoft Entraで保護されたツールを接続してユーザーごとのアクセスを行います。 どちらも OAuth ID パススルーを使用するため、各ダウンストリーム呼び出しは接続を承認するユーザーとして実行されます。
1. 各ツールの接続を作成する
# Private orders MCP: OAuth identity passthrough
azd ai connection create orders-mcp \
--kind remote-tool \
--target https://orders-mcp.example.com/mcp \
--auth-type oauth2 \
--authorization-url https://auth.example.com/authorize \
--token-url https://auth.example.com/token \
--client-id <oauth-client-id> \
--client-secret <oauth-client-secret> \
--scopes "openid offline_access orders.read"
# Work IQ: OAuth identity passthrough
azd ai connection create workiq-conn \
--kind remote-a2a \
--target https://workiq.svc.cloud.microsoft/a2a/ \
--auth-type oauth2 \
--authorization-url https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize \
--token-url https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token \
--client-id <oauth-client-id> \
--client-secret <oauth-client-secret> \
--scopes "api://workiq.svc.cloud.microsoft/WorkIQAgent.Ask offline_access"
2. 両方のツールをツールボックスに追加する
各ツールは、ID で接続を参照します。 この単一参照は、共有サービス アカウントとして実行することと、サインインしているユーザーの代わりに動作することの違い全体です。 エージェントには、トークン ブローカーやユーザーごとのトークン キャッシュは必要ありません。
この例では、azure-ai-projects (Python) または @azure/ai-projects (TypeScript) バージョン 2.3.0 以降が必要です。
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import MCPToolboxTool, WorkIQPreviewToolboxTool
endpoint = "https://<your-foundry-account>.services.ai.azure.com/api/projects/<your-project>"
project = AIProjectClient(endpoint=endpoint, credential=DefaultAzureCredential())
orders_connection = project.connections.get("orders-mcp")
workiq_connection = project.connections.get("workiq-conn")
toolbox_version = project.toolboxes.create_version(
name="employee-toolbox",
description="Private orders MCP + Work IQ, both via OAuth identity passthrough.",
tools=[
MCPToolboxTool(
server_label="orders",
server_url="https://orders-mcp.example.com/mcp",
require_approval="never",
project_connection_id=orders_connection.id,
),
WorkIQPreviewToolboxTool(project_connection_id=workiq_connection.id),
],
)
print(f"Created toolbox: {toolbox_version.name}, version: {toolbox_version.version}")
JavaScript については、保守されている ツールボックス プロジェクト接続のサンプル と Work IQ のサンプルを参照してください。 最初のサンプルでは、プロジェクト接続を使用してエージェントにアタッチする MCP ベースのツールボックスを作成します。 2 番目のサンプルは、Work IQ プロジェクト接続を参照する方法を示しています。
3. エージェントをツールボックスに接続する
エージェントはツールボックスの単一コンシューマー エンドポイントに接続します。これは常に既定のバージョンを提供します。 エージェントは、独自の ID を使用してプラットフォームに対して認証を行います。 Foundry は、ツールごとに、OAuth 承認を完了したユーザーを表す資格情報を提供します。 エージェントには、ツールごとの認証コードはありません。
from azure.identity import DefaultAzureCredential
from agent_framework import FoundryToolbox
# Agent-to-toolbox identity: the agent's own credential, scoped to the platform
credential = DefaultAzureCredential()
, timeout=120.0)
# Consumer endpoint always resolves to the toolbox's default version
CONSUMER_URL = f"{endpoint}/toolboxes/employee-toolbox/mcp?api-version=v1"
toolbox = FoundryToolbox(
name="employee_toolbox",
url=CONSUMER_URL,
http_client=http_client,
load_prompts=False,
)
agent = chat_client.as_agent(
name="employee-agent",
instructions="Help employees with their orders and Microsoft 365 context.",
tools=[toolbox],
)
Foundry は、特定のユーザーが初めてツールを承認する必要がある場合に同意リンクを生成します。 同意した後の呼び出しでは、そのユーザーの資格情報が使用されます。 更新トークンの有効期限が切れた場合、または取り消された場合、ユーザーはツールの承認を再度行う必要がある場合があります。
Note
OAuth ID パススルーを使用するエージェントのコンシューマーには、少なくともプロジェクトに対する Foundry Agent Consumer ロールが必要です。 ユーザーの Microsoft Entra テナントは Foundry プロジェクトのテナントと一致している必要があります。テナント間トークン交換はサポートされていません。
パススルーを超えて:ツールボックスが提供するもの
認証とツールのトラフィックはツールボックスを通過するため、クリーンな ID 処理以上のものが得られます。
- 責任ある AI ガードレール。 Guardrail は、すべてのツールの入力と出力を画面に表示するため、信頼されていない MCP 応答では、プロンプトインジェクションや安全でないコンテンツをエージェントに戻すことはできません。
- 独自のAIを持ち込めるAIゲートウェイ。 レート制限、ログ記録、およびネットワーク ポリシーのために、Azure API Management (APIM) を使用して MCP サーバーを前面に出します。
- バージョン管理。 新しいツールボックス バージョンを作成してテストし、それを既定に昇格します。 コンシューマー エンドポイントを指すすべてのエージェントは、コードを変更せず、昇格されたバージョンを自動的に取得します。