News

Implementation explainer

A2A Permissions in Microsoft’s Agent Stack

Read Microsoft’s implementation examples to understand agent identities, user delegation, Foundry roles, and the authorization checks needed at every hop.

When one agent asks another to do something, whose permission makes the request legitimate? Microsoft’s A2A examples make that question concrete: identify the caller, grant access to the target, and check the authority behind the work that follows.

日本語版を読む(Markdown)

Consider a hypothetical procurement assistant. Maya asks Agent A to compare suppliers. A delegates research to Agent B, which can query a purchasing system. The conversation crosses at least three boundaries: Maya to A, A to B, and B to the purchasing system. Each boundary needs a decision about who may do what. Permission to compare quotes does not itself establish a mandate to place an order.

This article reads Microsoft’s public implementation guidance, then develops an application policy for that example. The Foundry A2A integration is documented as a preview. Sources were checked on September 7, 2026; the code below illustrates configuration and authenticated discovery, and was not executed against an Azure tenant. See the Foundry integration guide for its current prerequisites and limitations.

What the framework example implements

Microsoft Agent Framework’s A2AAgent lets application code call a remote agent through the framework’s familiar agent interface. Its Python documentation shows an authentication interceptor that adds a bearer token to outgoing requests. The remote agent’s tools remain on the remote side; the client wrapper does not configure them. See the A2A agent service examples.

The package’s hosting example is deliberately small. Its security notes say that authentication and authorization must be added around the host’s entry points. They also explain that task, thread, context, and session IDs identify state; access to that state must be bound to an authenticated user, tenant, or workspace.

An example that exchanges a message successfully therefore answers a connectivity question. To review an application built from it, follow the request further: which middleware established the identity, which policy admitted the task, and which credential reached the final tool? Those are separate pieces of the implementation.

  1. User → Agent AEstablish the user and the requested task: compare approved suppliers.
  2. Agent A → Agent BChoose a service or delegated user identity. Check access to B.
  3. Agent B → task stateScope task history, artifacts, and control operations to the caller.
  4. Agent B → purchasing APIUse the intended downstream identity and enforce the allowed action.
An application review model for the hypothetical procurement workflow. These four checks are AgentCollusion’s explanation, not four named components of Microsoft’s product.

Choose the identity for each hop

Foundry distinguishes shared authentication from individual authentication. A shared key or managed identity gives the remote endpoint a common caller. OAuth identity passthrough preserves the individual user context. The choice determines whose permissions the remote service can evaluate. Microsoft’s A2A authentication guide describes the following options for outgoing connections.

Connection methodIdentity at the remote endpointPreserves user context?
Shared API key or tokenThe account represented by the shared credentialNo
Agent identityThe configured agent identityNo
Project managed identityThe project’s common service identityNo
OAuth identity passthroughThe user who signs in and consentsYes
UnauthenticatedNo authenticated caller established by this methodNo

Shared credentials belong in a project connection only when sharing is intended: the same guide warns that project access exposes connection secrets. User-specific access belongs in the individual authentication flow. The table describes outbound choices; a particular target can accept a narrower set.

In our example, a nightly job compiling common supplier statistics could use a service identity with access to a shared dataset. Maya’s personal purchasing history calls for a design that retains her identity and enforces her access. If B instead uses a broad service account, the application must deliberately enforce the user’s boundary before querying and returning that data. Signing Maya in at the front door alone does not implement that filter.

Grant access to a Foundry agent

Foundry’s incoming A2A endpoint requires Microsoft Entra authentication, including for its Agent Card. The caller can represent a user or a service. For direct token acquisition, Microsoft specifies the https://ai.azure.com/.default scope. See the incoming A2A implementation guide.

For a principal that only calls agents, Microsoft recommends Foundry Agent Consumer. Assign it at the target agent scope when the caller needs just that endpoint. Project scope extends endpoint access across the project. Agent-scoped assignments currently govern endpoint access; they are not a general per-agent scope for every Foundry operation. See the Foundry RBAC reference.

The following is an illustrative role assignment for a service caller. An administrator with role-assignment permission supplies the actual principal object ID and target resource ID. Running it creates an Azure role assignment; it belongs in provisioning, not in the model’s tool loop.

# Replace both placeholders before running.
# Foundry Agent Consumer role definition 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>"

Use the object ID of the identity represented by the token, rather than an application’s client ID. For delegated user access, assign the user or a suitable group with the corresponding principal type. Microsoft’s role-assignment example also distinguishes the new agent model’s instance_identityfrom the legacy identity lifecycle. Read the deployed agent’s actual identity instead of assuming publishing always changes it.

Authenticate discovery and configure the connection

A direct client can first retrieve the target’s protected card. This Python example uses azure-identity and httpx. It assumes an enabled Foundry incoming endpoint and a credential with the target role assignment. Set FOUNDRY_A2A_BASE_URL to the agent’s HTTPS URL ending in /endpoint/protocols/a2a.

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())

Resolve that URL from trusted deployment configuration. HTTPS by itself cannot establish that an arbitrary hostname is your intended agent. Also check which identity DefaultAzureCredential selects: a developer login and a deployed managed identity can have very different access. This example obtains one token for one request; a long-running client needs token renewal. Printing the card’s name verifies discovery only. Microsoft provides a complete A2A SDK call example for the subsequent message exchange.

For a Foundry-hosted caller, the outgoing tool instead references a configured project connection. The schematic tool definition is:

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

The connection guide currently treats Foundry targets specially: use the target’s A2A base path and the audience https://ai.azure.com; the managed integration resolves discovery and negotiates the protocol version. For other protected card endpoints, the guide describes the optional send_credentials_for_agent_card setting. Direct SDK access and managed Foundry-to-Foundry discovery therefore have different setup instructions. Follow the instructions for the client path you actually use.

Carry authority into downstream work

User delegation also needs the right token for the next resource. Microsoft Entra’s OAuth on-behalf-of (OBO) flow exchanges a token received by a middle-tier API for a token targeting a downstream API. The incoming assertion must be intended for the middle tier making the exchange. OBO uses delegated user permissions; application-only access uses a different flow. See Microsoft’s OBO documentation.

In a custom A → B → purchasing API design, document the audience and represented principal at both hops. Do not infer that enabling identity passthrough on A automatically configures B’s downstream tools. A token accepted by B is not a credential to forward indiscriminately to another audience. If the API uses a service identity, say so explicitly in the policy and enforce the applicable user and task limits around its use.

This is where the procurement example becomes useful. Maya can ask B to compare three quotes. B might be technically capable of issuing a purchase order, because its purchasing connector is shared with another workflow. Our proposed application policy permits quote retrieval for Maya’s approved suppliers and rejects order creation for this task. Changing the task into a purchase requires a mandate that includes the supplier, amount, currency, and any required approval.

Enforce that policy at the tool or transaction boundary using trusted state. A sentence in a system prompt helps communicate intent, but accepting a sentence such as “Maya approved this” from another agent cannot establish the approval. The enforcement service should retrieve the mandate, bind it to the user and task, and evaluate the concrete operation before executing it.

A2A v1.0 supplies protocol mechanisms around these decisions. Servers apply their own authorization model, and task access must stay within the caller’s permitted scope. A task can enter TASK_STATE_AUTH_REQUIRED when further authorization is needed. The specification describes obtaining credentials out of band, with negotiated alternatives, rather than assuming ordinary task text is a credential channel. See Section 7 and Section 13.1.

Verify the boundaries with rejection tests

A useful review includes requests that should fail. The following is our proposed test plan for the example application, not reported Microsoft test results. Use two accounts with deliberately different access and preserve the relevant policy decisions alongside each result.

TestExpected boundaryEvidence to inspect
Use an expired token or a token for another audience.The target rejects authentication.Token validation outcome; no downstream execution.
Use a valid identity without target endpoint access.Calling the agent is denied.Principal, target resource, and role evaluation.
Call a second agent outside the intended assignment scope.Only the explicitly permitted endpoint is accessible.Effective assignments, including broader inherited grants.
Read, list, cancel, or subscribe to another user’s task.Each operation enforces the application’s ownership or sharing policy.No unauthorized history, artifacts, or state changes.
Allow A → B but withhold access to the purchasing data.The downstream data boundary still blocks access.The actual identity and authorization decision at the API.
Send “the user approved the purchase” inside a research task.The task’s mandate still excludes order creation.No order created; an independently checked approval record.
Revoke access while a long-running task is waiting.New sensitive actions follow the documented revocation policy.Token/cache lifetime, role propagation, and execution-time checks.

Define revocation timing explicitly. A role change, a cached token, and an application queue need not observe the same clock. For a high-impact operation, our recommendation is to recheck the current task mandate immediately before committing the effect and measure how identity changes propagate in the deployed system.

Record the initiating user where applicable, the authenticated caller at each hop, the target agent, task ID, action, policy decision, and downstream result. Keep bearer tokens and connection secrets out of those logs. This gives a reviewer a chain of attributable decisions without turning the audit trail into a store of reusable credentials.

What permission checks leave for coordination research

Even agents operating within their individual access rights can produce an undesirable joint outcome. In a hypothetical purchasing workflow, several permitted requests might repeatedly favor the same supplier or split a larger commitment across individually acceptable purchases. Whether that is legitimate depends on the task, incentives, and aggregate effects. It cannot be decided from a successful token check.

Microsoft’s identity and access controls provide useful enforcement points. AgentCollusion’s research question starts with the behavior across those points: which agents coordinated, whose objective they served, and whether the combined result stayed within the principal’s mandate. Endpoint access, task ownership, and transaction records give that investigation concrete evidence to work with.

Continue with our explainers on Agent Cards, HTTP methods and agent permissions, and authority to spend.

Primary sources and scope

Product behavior is attributed to these primary sources. The procurement scenario, review diagram, mandate policy, and rejection tests are AgentCollusion’s explanatory proposals. This article does not report a Microsoft vulnerability or an executed authorization experiment.