Skip to main content
The gateway calls a Microsoft agent that is exposed as an A2A server, minting an Entra (Azure AD) OAuth token per request and forwarding it. It supports both the app-identity flow (client_credentials) and the delegated flow (on_behalf_of) where the real end-user identity is carried through
This is the outbound direction: ForceAI reaches into Microsoft. For the reverse, where Copilot Studio or a declarative agent calls ForceAI as a tool, see the Microsoft 365 Tool Adapter.

Prerequisites (Microsoft side)

1

Expose the agent as an A2A server

The target must be a reachable HTTPS A2A endpoint with an agent card. Built-in M365 Copilot agents (Researcher, Analyst) and plain Copilot Studio agents do not qualify; host the agent with the Microsoft Agent Framework (agent-framework-a2a, A2AExecutor) or the M365 Agents SDK. The endpoint looks like https://<host>/a2a/<agent>/v1/message:stream, with the card at <endpoint>/.well-known/agent-card.json
2

Register an Entra app for ForceAI

In Azure Portal -> Microsoft Entra ID -> App registrations -> New registration, create the app ForceAI authenticates as. Copy the Tenant ID and Client ID, then create a client secret under Certificates and secrets
3

Set the scope and consent

The scope is the App ID URI of the app protecting the target agent plus /.default, for example api://<agent-app-id>/.default. For client_credentials, grant the application permission on the target and click Grant admin consent, otherwise the token is issued but the downstream call is rejected

The two Entra flows

ForceAI calls the agent as itself. Simplest to set up. Requires admin consent on the target API. Use when the agent does not need to act as a specific end user

Register the agent

The M365 backend is a native A2A server, so there is no model template. Set a2a_backend to m365_copilot, put the agent’s A2A endpoint in agent_card_params.url, and supply the Entra fields
Or in the dashboard: Agentic -> Agents -> Add New Agent, pick Microsoft 365 Copilot (A2A), and fill the Entra fields plus the agent endpoint URL

Fields

string
required
m365_copilot. Note this backend uses a2a_backend, not custom_llm_provider
string
required
The agent’s A2A endpoint, for example https://<host>/a2a/<agent>/v1/message:stream
string
required
The Entra app ForceAI authenticates as
string
required
App ID URI of the target plus /.default, for example api://<agent-app-id>/.default
string
default:"client_credentials"
client_credentials or on_behalf_of

Approve and invoke

For on_behalf_of, add the caller’s Entra token so the agent runs as the end user:
The gateway mints and caches the Entra bearer per request (refreshed shortly before expiry) and forwards it to the M365 A2A endpoint. In Logs the request is attributed to the azure provider
If a client_credentials call returns a token but the agent still rejects the request, admin consent is missing on the target API. Grant admin consent on the app registration and retry