-
Notifications
You must be signed in to change notification settings - Fork 284
Description
Is your feature request related to a problem? Please describe.
When building a Declarative Agent that calls Microsoft Graph (/admin/serviceAnnouncement/messages), we could not get SSO working via identityProvider: MicrosoftEntra on the oauth/register step. The OBO (On-Behalf-Of) token exchange silently fails — Entra ID sign-in logs show the initial SSO token is issued successfully (scoped to the agent's own API), but the platform never performs the OBO exchange to acquire a Microsoft Graph access token. There is no error surfaced to the developer; the agent simply fails to retrieve data. Additionally, Entra ID sign-in logs recorded error 50011 (redirect URI mismatch), indicating the platform sends a redirect URI during the SSO flow that doesn't match what's configured on the Entra ID app registration — and the developer has no visibility into or control over what redirect URI the platform constructs.
Describe the solution you'd like
- Fix the OBO token exchange — When
identityProvider: MicrosoftEntrais set and the SSO token is successfully obtained, the platform should execute the OBO exchange to acquire a downstream API token (e.g., Microsoft Graph) and surface a clear error if it fails. - Surface diagnostic information — Provide logging or error output when the SSO+OBO flow fails, rather than failing silently. Developers should not need to manually inspect Entra ID sign-in logs to debug authentication issues.
- Resolve the redirect URI mismatch — The platform should either automatically configure the correct redirect URIs on the Entra ID app during
oauth/register, or document exactly which redirect URIs must be present for SSO to work. - Clarify
identifierUrisownership — Document the interaction betweenoauth/register(which sets the Application ID URI toapi://auth-{guid}/{clientId}) andaad.manifest.json(which can also defineidentifierUris). Setting it in the wrong place silently breaks the flow. - Provide an end-to-end SSO+OBO sample — Publish a Declarative Agent sample that uses SSO to call Microsoft Graph as a downstream API, covering the full
aadApp/create→aadApp/update→oauth/registerlifecycle.
Describe alternatives you've considered
-
Implementing the OBO token exchange in custom code — In a traditional Bot Framework or Azure Function–backed agent, we could intercept the SSO token and call the Entra ID
/oauth2/v2.0/tokenendpoint withgrant_type=urn:ietf:params:oauth:grant-type:jwt-bearerto exchange it for a Microsoft Graph token ourselves. However, Declarative Agents have no custom backend — they are purely manifest-driven configurations where the platform owns the entire auth and API call pipeline. There is no code entry point where a developer can insert an OBO exchange. This is why we need the platform to handle the OBO leg natively whenidentityProvider: MicrosoftEntrais set. -
Standard OAuth2 authorization code flow (current workaround) — We replaced SSO+OBO with OAuth2 auth code flow using PKCE + client secret (confidential client). This requires a one-time interactive consent prompt instead of silent SSO, but actually works. Specifically:
- Removed
identityProvider: MicrosoftEntrafromoauth/register - Added
clientId,clientSecret, andisPKCEEnabled: truetooauth/register - Added
aadApp/createandaadApp/updatesteps to the provision lifecycle inm365agents.yml - Added explicit scopes (
https://graph.microsoft.com/ServiceMessage.Read.All) to the OpenAPI spec's operation-level security
With a confidential client, refresh tokens last ~90 days, so users only re-authenticate after prolonged inactivity. The UX trade-off is acceptable but SSO would be the ideal experience.
- Removed
Additional context
- Error evidence: Entra ID sign-in log entry with error code 50011 is captured in our repo at
dev/signin-50011.json— the failure reason states the redirect URI in the request does not match the redirect URIs configured for the application. - Sign-in log observation: Logs showed successful AAD Graph SSO completions but zero Microsoft Graph token requests, confirming the OBO leg never fired.
- Entra ID app config: The app registration included all required configuration —
access_as_userscope, pre-authorized Teams/Office client app IDs, correct redirect URIs,idtypoptional claim, andrequiredResourceAccessforUser.Read+ServiceMessage.Read.All. - Architecture constraint: Declarative Agents are entirely manifest-driven with no custom backend. The platform is the only component that can perform the OBO exchange — there is no developer code path to work around this.
- Toolkit versions: M365 Agents Toolkit,
m365agents.ymlschema v1.8.