APIM × Foundry IQ の ACL を使った ユーザー別アクセス制御 MCP を実装してみた

>100 Views

September 09, 26

スライド概要

API Management とFoundry IQ の ACL を使って、ユーザー別アクセス制御 MCPを実装してみました。
前半で Foundry IQ の概要と ACL の仕組みを整理し、後半で API Managementと Foundry IQ を組み合わせた際の実装の工夫点をご紹介します。

profile-image

プラットフォームエンジニアです。 セキュリティやSRE、インフラなど多岐にやっています。 趣味はタロット。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

APIM × Foundry IQ の ACL を使った ユーザー別アクセス制御 MCP を実装 してみた

2.

目次 1. Foundry IQ の概要と ACL 2. APIM × Foundry IQ の ACL を使ったユーザー別ア クセス制御 MCP 3. ハンズオン紹介

3.

Foundry IQ の概要と ACL

4.

Foundry IQ とは  エージェントに 社内データへの許可ベースのアクセスを与える、Azure AI Search 上に構築されたマネージド知識レイヤー  中核となる3つのコンポーネント コンポーネント 役割 Knowledge Base ナレッジソースをまとめる最上位リ ソース。検索の推論強度(reasoning effort)などの挙動を定義 Knowledge Source Blob / SharePoint / OneLake / 既存 Indexなど、実データへの接続 Agentic Retrieval 質問を複数のサブクエリに分解し、 並列実行・リランクして統合回答を 返すエンジン

5.

ACL とは何を指すか  Foundry IQ / Azure AI Search は クエリ時にユーザー権限を強 制 し、呼び出したユーザーが閲覧を許可されたドキュメント のみを返す  キーとなるのが `x-ms-query-source-authorization` ヘッダー  呼び出し元(エージェント/クライアント)が保持する `search.azure.com` スコープのトークンを そのまま Foundry IQへ転送  「ACL判定のためのユーザー識別情報」として利用される。

6.

x-ms-query-source-authorization を軸に整理  ユーザーコンテキストの伝播 クライアントが取得した `search.azure.com` 向けトークンを、 SDKまたは MCP を経由して AI Search まで無加工で運ぶ  Search 側での ACL 判定 `permissionFilterOption: "enabled"` を有効化したインデックスが、トークンの ID を `UserIds` / `GroupIds` / `RbacScope` と突き合わせて絞り込む  認証パススルーとの関係 authorizationヘッダーは、マネージドIDかユーザーのトークンだが、この ACL ヘッダーだけは ユーザー本人のトークンをパススルー させる、二層構造 になっている

7.

`x-ms-query-source-authorization`でデータアクセス制御 が可能なナレッジソース  ADLS Gen2 / Blob の POSIX ライクな ACL・RBAC スコープ(今回の実装)  Microsoft Purview の機密ラベル(Blob / ADLS / SharePoint / Fabric OneLake)  SharePoint (M365) の ACL(サイトグループ含む、インデックス済みコンテン ツ)  リモート SharePoint ナレッジソース(Copilot Retrieval API でライブに強制)  Fabric Data Agent / Fabric IQ(トークンを Fabric 向けに OBO 交換して問い合 わせ)

8.

APIM × Foundry IQ の ACL を 使ったユーザー別アクセス制御

9.

シーケンス図 API Management(APIM) → Azure Functions → Foundry IQ(AI Search) の主要3ホップに絞って整理

10.

工夫点① 実装まわりの要点  コスト/レイテンシの調整  `reasoning_effort` を明示指定(既定値に任せると課金対象の reasoning tokensが増加)  `max_runtime_in_seconds` でサーバー側の検索処理時間に上限を設定  `output_mode=EXTRACTIVE_DATA` は固定とし、回答合成はMCP呼 び出し元(エージェント)に委ねる  セキュアコーディング: 例外の詳細はログのみに残し、MCP呼び出し元に は `"Forbidden"` などの固定メッセージだけを返却  秘匿情報の扱い: トークンの有無は `acl_header_present` という真偽値の みを記録し、トークン自体は決してログ/トレースに残さない  部分失敗の可視化: AI Search が一部ナレッジソースの取得に失敗しても 例外にならない(HTTP 206)ため、activity配列を明示的に走査して警告 ログを出す

11.

工夫点② Functions は必ず APIM 経由にする設計  Functions 側は Easy Auth(Entra ID)に加え、アプリケーションロール `Mcp.Invoke` の保持をコード内でチェック  このロールを持てるのは次の2者のみ  APIM の管理ID(システム割り当てMI) — 本番トラフィックはすべてこ こを通る  運用チームの Entra ID グループメンバー — トラブルシュート用の直接ア クセス(実運用では、PIMと併用を推奨)  通常のエンドユーザーは 必ず APIM を経由 し、Function は「ユーザー本人の トークン」を認可判定には使わない構造

12.

工夫点③ APIM を「トークンブローカー」にする狙い apim-mcp-oauth (次ページ参照)が確立したパターンを踏襲 1. 2. 3. `validate-azure-ad-token` で署名・issuer・audience・有効期限を検証 `authentication-managed-identity` で APIM の MI トークンを取得 `Authorization` ヘッダーを MI トークンに差し替えてバックエンドへ転送 → 前頁で説明したように、バックエンド側では Mcp.Invoke ロールを必ず確認するた め、エンドユーザーが直接バックエンドへ到達する経路は存在せず、呼び出しは常に APIM を経由する設計になる。APIM が認証トークンの検証と差し替えを担う一方で、 ACL 判定に必要なユーザー識別情報だけは` x-ms-query-source-authorization` ヘッダーで 別途運ぶことで、「認可の仲介」と「本人性の伝播」を明確に分離している。

13.

ハンズオン紹介 今回のスライドは、以下ハンズオンシリーズの一部(追加MCP編)です。 1 → 2 →3 の順に既存 APIM 環境の上に積み上げてazd upでデプロイします。 ぜひ試してみてください! 1. https://github.com/apc-n-orita/apim-mcp-oauth : APIM × MCP × OAuth のエンドツーエンド保護の土台。`Mcp.Invoke` ロールと MCPツール別認可のトークンブローカーパターンを構築 2. https://github.com/apc-n-orita/apim-mcp-a2a-oauth : 上記に Microsoft Foundry A2A / 追加 MCP(今回の `foundryiq-acl-mcp`, `Foundry toolbox`)を積み増し 3. https://github.com/apc-n-orita/APICenter : APIM 上の API/Agent/MCP を API Center カタログへ集約・公開