Microsoft Foundry でのツールボックス認証のしくみ

Microsoft Foundry のツールボックス認証によって、ツールがダウンストリーム サービスに対してどのように認証されるかが決まります。 認証設定はプロジェクト接続で構成され、エージェントは、エージェント コードに認証ロジックを実装せずに、匿名アクセス、共有資格情報、サービス ID、またはサインインユーザーの ID を使用できます。

この記事では、ツールボックス認証のしくみについて説明し、各ユーザーのアクセス許可とアクセス境界を維持しながら、プライベート MCP サーバーと Work IQ の OAuth ID パススルーを構成する方法について説明します。

ツールボックスは、接続の認証を一元化します。 認証は接続のプロパティであり、エージェント内のコードではありません。 ツールを接続すると、認証の種類を選択し、Foundry はサービス側でトークンの取得、交換、更新、挿入を処理します。 エージェント コードは、認証フローではなくビジネス ロジックに重点を置いたままになります。

ユーザーごとの認証が自分で構築するのが難しい理由

Entra で保護されたツールへのユーザー単位のアクセス制御を自分で実装すると、気づきにくい形で誤りを生みやすい、セキュリティ上重要な基盤処理を自ら担うことになります。

  1. ユーザーごとのトークン分離を自分で実装します。 ユーザーとテナントによってトークン キャッシュを正しくパーティション分割する必要があります。 キャッシュ キーが間違っていると、あるユーザーのダウンストリーム API アクセスが別のユーザーにサイレント モードで漏えいする可能性があります。これは、すべての機能テストに合格するバグです。
  2. リソースごとに、ユーザーごとの同意とライフサイクルを管理します。 AADSTS65001などの同意エラーを検出し、同意を通じてユーザーを送信し、期限切れのトークンを更新し、作成するすべてのエージェントで API ごとに 401/403 回の再試行を正しく処理する必要があります。
  3. ツールやエージェントに比例して増大する複雑さを吸収します。 新しいツールごとに、別のスコープ、トークン交換、キャッシュ エントリ、同意パス、再試行パス、ヘッダー パスが追加されます。 何百ものツールと何千ものエージェントにスケーリングすると、同じ脆弱な配管を何度も繰り返し再構築します。

すべてのツール呼び出しの 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 サービス。

oauth2user-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 サーバーを前面に出します。
  • バージョン管理。 新しいツールボックス バージョンを作成してテストし、それを既定に昇格します。 コンシューマー エンドポイントを指すすべてのエージェントは、コードを変更せず、昇格されたバージョンを自動的に取得します。