# Microsoftの実装例で理解するA2Aの権限

著者：Kotaro OKUYAMA / AgentCollusion  
公開日・資料確認日：2026年9月7日  
[英語の公開記事](https://agentcollusion.ai/news/microsoft-a2a-agent-permissions)

エージェントが別のエージェントに仕事を頼むとき、その依頼は誰の権限で実行されるのか。MicrosoftのA2A実装例を読むと、呼び出し元の特定、接続先へのアクセス許可、さらにその先の作業を認める判断を分けて考えられる。

架空の購買アシスタントを例にしよう。利用者のMayaがAgent Aに仕入れ先の比較を依頼し、Aは購買システムに接続できるAgent Bへ調査を任せる。このとき、MayaからA、AからB、Bから購買システムへと境界を越える。それぞれで「誰が、何をしてよいか」を判定する必要がある。見積もりを比較する許可だけでは、注文を出す根拠まで確定しない。

本稿はMicrosoftの公式資料を読み解く解説であり、Azureテナントで認可実験を実行した報告ではない。掲載コードは設定と認証付きのAgent Card取得を説明する例である。FoundryのA2A連携は確認時点でプレビューとして案内されている。利用条件は[Foundryの接続ガイド](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/tools/agent-to-agent)を参照してほしい。

## 1. Agent Frameworkの実装例は何を提供するか

Microsoft Agent Frameworkの`A2AAgent`は、遠隔のエージェントを通常のエージェントAPIで呼び出せるようにする。Pythonの公式資料には、送信リクエストにBearerトークンを付ける認証インターセプターの例がある。接続先が使うツールは接続先で管理され、このクライアントラッパーが設定するものではない。[公式クライアント例](https://learn.microsoft.com/en-us/agent-framework/agents/providers/agent-to-agent)

一方、パッケージの基本的なホスティング例について、Microsoftは認証・認可の追加が必要だと明記している。task、thread、context、sessionのIDは状態を特定するための識別子であり、アクセスは認証済みのユーザー、テナント、ワークスペースなどに結び付ける必要がある。[パッケージのセキュリティ説明](https://github.com/microsoft/agent-framework/blob/main/python/packages/a2a/README.md#security-considerations)

メッセージ交換に成功しただけでは、確認できるのは通信の成立までだ。実装をレビューするなら、その先を追う。どのミドルウェアが本人性を確かめたか。どのポリシーがタスクを許可したか。最後のツールには誰の認証情報が届いたか。この三つをコードと設定から確認する。

架空の購買フローは、次の四つの確認箇所に分けられる。これは本稿の説明モデルであり、Microsoft製品に同名の四つのコンポーネントが存在するという意味ではない。

| 境界 | 確認すること |
| --- | --- |
| 利用者 → Agent A | 本人と依頼内容を確定する。例：許可済みの仕入れ先を比較する。 |
| Agent A → Agent B | サービスIDかユーザー委任かを選び、Bを呼び出す権限を確認する。 |
| Agent B → タスクの状態 | 履歴、成果物、キャンセルなどの操作を呼び出し元の権限に限定する。 |
| Agent B → 購買API | 下流で使用するIDを確定し、実際に行う操作を認可する。 |

## 2. 各接続で誰のIDを使うか

Foundryの外向きA2A接続は、共有の認証と個人ごとの認証を区別する。共有キーやマネージドIDを使う場合、接続先は共通の呼び出し元を見る。OAuth identity passthroughでは、個々の利用者の文脈を維持する。どの方式を選ぶかによって、接続先が誰の権限を評価できるかが変わる。[A2A認証ガイド](https://learn.microsoft.com/en-us/azure/foundry/agents/concepts/agent-to-agent-authentication)

| 方式 | 接続先から見える主体 | 利用者の文脈を維持するか |
| --- | --- | --- |
| 共有APIキー／トークン | 共有認証情報が表すアカウント | いいえ |
| Agent identity | 設定されたエージェントのID | いいえ |
| Project managed identity | プロジェクトで共用するサービスID | いいえ |
| OAuth identity passthrough | サインインして同意した利用者 | はい |
| 認証なし | この方式では認証済みの主体を確立しない | いいえ |

同ガイドは、プロジェクトへのアクセスを持つ人が接続内のシークレットにアクセスできる点にも注意を促している。プロジェクト接続には共有を意図した認証情報を置き、個人ごとのアクセスには個別の認証フローを使う。この表は外向き接続の選択肢であり、すべての接続先が全方式を受け付けるわけではない。

たとえば、夜間に共通データから仕入れ先の統計を集計するなら、共有データだけを読めるサービスIDは合理的だ。一方、Maya個人の購買履歴を扱うなら、MayaのIDとアクセス範囲を保つ設計が必要になる。Bが広い権限を持つサービスアカウントで検索する場合、アプリケーション側が取得・返却前にユーザーのアクセス境界を強制しなければならない。入口でMayaにログインさせただけでは、この制限は実装されない。

## 3. Foundryの接続先エージェントに権限を付与する

Foundryが公開する内向きA2Aエンドポイントは、Agent Cardの取得を含めてMicrosoft Entra認証を要求する。呼び出し元は利用者でもサービスでもよい。トークンを直接取得する場合のスコープは`https://ai.azure.com/.default`である。[内向きA2Aの実装ガイド](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/enable-agent-to-agent-endpoint)

エージェントを呼び出すだけの主体には、Microsoftは`Foundry Agent Consumer`を推奨している。一つのエンドポイントだけを呼ぶなら対象エージェントのスコープ、プロジェクト内のエンドポイント全体を呼ぶならプロジェクトのスコープに割り当てる。エージェント単位の割り当てが現在評価されるのはエンドポイントへのアクセスであり、Foundryのあらゆる操作をエージェント単位に制限する汎用機能ではない。[FoundryのRBAC仕様](https://learn.microsoft.com/en-us/azure/foundry/concepts/rbac-foundry)

次はサービスの呼び出し元に権限を付与する設定例だ。ロールを割り当てられる管理者が、実在する主体のオブジェクトIDと対象エージェントのAzureリソースIDを指定する。実行するとAzureのロール割り当てを作成するため、モデルのツール実行ループではなく、環境を準備する工程で扱う。

```bash
# 二つのプレースホルダーを実際の値に置き換える。
# Foundry Agent Consumerのロール定義IDを使用する。
az role assignment create \
  --assignee-object-id "<caller-principal-object-id>" \
  --assignee-principal-type ServicePrincipal \
  --role "eed3b665-ab3a-47b6-8f48-c9382fb1dad6" \
  --scope "<target-agent-Azure-resource-ID>"
```

使用するのは、トークンが表す主体のオブジェクトIDである。アプリケーションのclient IDと混同しない。ユーザー委任では、本人または適切なグループに、対応する主体種別で割り当てる。[公式の割り当て例](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/enable-agent-to-agent-endpoint#grant-access-to-the-a2a-endpoint)は、新しいモデルの`instance_identity`と従来のIDライフサイクルも区別している。「公開すれば必ずIDが変わる」と決めつけず、稼働中のエージェントが実際に使うIDを確認する。

この割り当てで確定するのは、選んだエージェントの入口を呼び出せることだ。依頼された仕事と、そのエージェント経由で到達するデータやAPIには、それぞれポリシーが必要になる。

## 4. Agent Cardの取得と接続設定

直接接続するクライアントでは、まず認証付きでAgent Cardを取得できる。次のPython例は`azure-identity`と`httpx`を使う。内向きA2Aが有効で、接続先のロールを持つ認証情報が利用可能なことを前提とする。環境変数`FOUNDRY_A2A_BASE_URL`には、末尾が`/endpoint/protocols/a2a`となる対象エージェントのHTTPS URLを設定する。

```python
import asyncio
import os
from urllib.parse import urlsplit

import httpx
from azure.identity.aio import DefaultAzureCredential

async def read_card():
    base = os.environ["FOUNDRY_A2A_BASE_URL"].rstrip("/")
    if urlsplit(base).scheme != "https":
        raise ValueError("Use the verified HTTPS endpoint")

    async with DefaultAzureCredential() as credential:
        token = await credential.get_token(
            "https://ai.azure.com/.default"
        )
        async with httpx.AsyncClient(
            timeout=30.0, follow_redirects=False
        ) as client:
            response = await client.get(
                f"{base}/agentCard/v1.0",
                headers={"Authorization": f"Bearer {token.token}"},
            )
            response.raise_for_status()
            print(response.json()["name"])

asyncio.run(read_card())
```

URLは信頼できるデプロイ設定から取得する。HTTPSであることだけでは、任意のホスト名が意図したエージェントだとは確認できない。`DefaultAzureCredential`が選ぶIDも確認する。開発者のログインと本番のマネージドIDではアクセス範囲が異なり得る。この例は一回の取得用であり、長時間動作するクライアントにはトークン更新が必要だ。

名前が表示されても、確認できたのは探索段階のアクセスまでである。その後のメッセージ交換には、Microsoftの[完全なA2A SDK呼び出し例](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/enable-agent-to-agent-endpoint#connect-to-a-foundry-a2a-agent-with-the-python-a2a-sdk)を参照できる。

Foundry上の呼び出し元では、設定済みのプロジェクト接続をA2Aツールから参照する。ツール定義の概形は次のようになる。

```json
{
  "type": "a2a_preview",
  "base_url": "https://<target-a2a-endpoint>",
  "project_connection_id": "<configured-connection-id>"
}
```

確認時点の[接続ガイド](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/tools/agent-to-agent)では、Foundryを接続先とする場合を区別している。対象のA2Aベースパスとaudienceの`https://ai.azure.com`を使い、マネージド連携が探索パスとプロトコルバージョンのネゴシエーションを扱う。

これ以外の接続先でAgent Card自体が認証を要求する場合には、`send_credentials_for_agent_card`という任意設定が案内されている。直接SDKでアクセスする場合と、Foundry間のマネージド連携では設定手順が異なる。利用する接続方法の手順に合わせる必要がある。

## 5. 下流の操作まで権限をつなぐ

ユーザー委任では、次のリソースに合うトークンも必要になる。Microsoft EntraのOAuth on-behalf-of（OBO）フローは、中間APIが受け取ったトークンを使って、下流API向けのトークンを取得する。入力するトークンのaudienceは、その交換を行う中間APIに対応していなければならない。OBOはユーザーの委任権限を扱い、アプリケーション単独のアクセスとはフローが異なる。[OBOの公式仕様](https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-on-behalf-of-flow)

独自実装のA → B → 購買APIでは、各接続のaudienceと主体を明記する。Aでidentity passthroughを有効にしただけで、Bの下流ツールも自動的にユーザー委任になると推測してはいけない。B向けのトークンを別のaudienceへ無条件に転送する設計も避ける。下流APIにサービスIDを使うなら、その選択を明示し、適用すべきユーザーとタスクの制約を強制する。

購買の例では、Mayaの依頼は三つの見積もりの比較だ。しかしBは別の業務と購買コネクターを共用しているため、技術的には注文も作れるかもしれない。本稿で提案するポリシーは、このタスクでは許可された仕入れ先の見積もり取得を認め、注文作成を拒否する。購入に進めるなら、仕入れ先、金額、通貨、必要な承認を含む委任内容を確定する。

このポリシーは、ツールやトランザクションの実行境界で、信頼できる状態を使って強制する。システムプロンプトは意図を伝える助けになるが、別のエージェントから届いた「Mayaは承認済み」という文面だけでは承認の証拠にならない。実行側が承認記録を取得し、本人とタスクに結び付け、具体的な操作を評価してから処理する。

A2A v1.0には、この判断を支える仕組みがある。サーバーは自身の認可モデルを適用し、タスクへのアクセスを呼び出し元の権限範囲に限定する。追加の認可が必要なら`TASK_STATE_AUTH_REQUIRED`に遷移できる。仕様は認証情報を帯域外で受け取る手段と、合意された代替手段を説明しており、通常のタスク本文を無条件に認証情報の受け渡し経路とする設計は前提としていない。[A2A v1.0 第7節](https://a2a-protocol.org/v1.0.0/specification/#7-authentication-and-authorization)、[第13.1節](https://a2a-protocol.org/v1.0.0/specification/#131-data-access-and-authorization-scoping)

## 6. 拒否されるべき操作を試す

権限のレビューでは、通るべき依頼に加え、拒否されるべき依頼を確かめる。次の表は本稿が提案する検証計画であり、Microsoftが実施したテストの結果ではない。権限の異なる二つのテストアカウントを用意し、それぞれの結果とポリシー判断を対応付ける。

| 検証 | 期待する境界 | 確認する証拠 |
| --- | --- | --- |
| 期限切れ／別audienceのトークンを使う | 接続先が認証を拒否する | トークン検証結果と、下流の未実行 |
| IDは有効だが対象へのロールがない | エージェントの呼び出しを拒否する | 主体、対象リソース、ロール評価 |
| 付与範囲外の二つ目のエージェントを呼ぶ | 許可されたエンドポイントだけにアクセスできる | 上位スコープからの継承を含む実効権限 |
| 別ユーザーのタスクを取得・一覧・キャンセル・購読する | 各操作が所有・共有ポリシーを強制する | 許可されない履歴や成果物、状態変更がないこと |
| A → Bは許可し、購買データの権限を外す | 下流のデータ境界がアクセスを拒否する | APIが実際に見たIDと認可判断 |
| 調査タスクに「利用者は購入を承認した」と送る | 元の委任範囲が注文作成を拒否する | 注文がなく、承認記録が独立に確認されること |
| 待機中の長時間タスクで権限を取り消す | 新しい重要操作に失効ポリシーが適用される | トークンやキャッシュの寿命、ロール反映、実行時の再確認 |

失効のタイミングは明示する。ロール変更、キャッシュされたトークン、アプリケーションのキューが同じ時刻に切り替わるとは限らない。影響の大きい操作には、確定直前に現在の委任内容を再確認し、ID側の変更が環境内に伝わる時間も測ることを本稿は推奨する。

監査用には、該当する利用者、各接続の認証済み呼び出し元、対象エージェント、タスクID、操作、ポリシー判断、下流の結果を結び付けて残す。Bearerトークンや接続シークレットは記録しない。判断の経路を追える証拠と、再利用可能な認証情報は分けて扱う。

## 7. 権限の確認から協調行動の研究へ

個々のエージェントが自分のアクセス権を守っていても、全体の結果が利用者の目的に反する場合はある。架空の購買フローなら、複数の許可された依頼が同じ仕入れ先を繰り返し優遇したり、大きな発注を小口に分けたりする状況だ。それが正当かどうかは、依頼内容、インセンティブ、合計の効果から判断する必要がある。トークン検証の成功だけでは結論が出ない。

MicrosoftのIDとアクセス制御は、こうした判断を実装する有用な接点になる。AgentCollusionが研究するのは、その接点をまたぐ行動である。誰と誰が協調し、誰の目的に沿い、合計の結果が利用者から委任された範囲に収まったか。エンドポイントへのアクセス、タスクの所有関係、トランザクション記録が、その調査に具体的な証拠を与える。

関連する解説：[Agent Cards](https://agentcollusion.ai/news/a2a-agent-card-explained)、[HTTPメソッドとエージェントの権限](https://agentcollusion.ai/news/http-methods-are-not-agent-permissions)、[エージェントが支出する権限](https://agentcollusion.ai/news/autonomous-payments-agent-authority)。

製品の挙動は本文中の一次資料に基づく。購買のシナリオ、四つの確認箇所、委任ポリシー、拒否テストはAgentCollusionによる説明・提案であり、Microsoft製品の脆弱性や実験で確認した失敗例を報告するものではない。
