-
Notifications
You must be signed in to change notification settings - Fork 249
Description
Summary
We are building a Custom Engine Agent for Microsoft 365 Copilot using the @microsoft/agents-hosting SDK (Node.js/TypeScript). The agent authenticates users via a third-party OAuth 2.0 provider (not Entra ID) configured as a Generic OAuth 2 connection in Azure Bot Service.
The issue: During sign-in, the Bot Framework opens a popup for the user to authenticate with the third-party provider. After the user completes authentication:
- In Teams direct chat (1:1): The popup closes automatically and the
signin/verifyStateinvoke is relayed back to the bot silently. The user never sees or copies a magic code. - In Microsoft 365 Copilot Chat: The popup shows a 6-digit magic/verification code and asks the user to manually copy and paste it into the chat window to complete sign-in.
This creates a poor user experience in Copilot Chat specifically.
Environment
- SDK:
@microsoft/agents-hostingv1.0.0 (Microsoft 365 Agents SDK for Node.js) - OAuth Connection: Generic OAuth 2 (third-party provider, not Entra ID)
- Manifest version: 1.24
- Agent type: Custom Engine Agent (
copilotAgents.customEngineAgents) - Channels affected: Microsoft 365 Copilot Chat only
- Channels working correctly: Teams personal chat (1:1)
What We've Tried
-
Added
webApplicationInfoto the Teams app manifest withapi://botid-{BOT_ID}— no effect (expected, since SSO token exchange only works with Entra ID). -
Set
enableSso: falseon the OAuth handler configuration — this correctly prevents the SDK from attempting SSO token exchange (which always fails for non-Entra ID providers), but the magic code popup still appears. -
Fixed the invoke activity handler to skip
signin/*activities so the SDK's authorization manager can processsignin/tokenExchangeandsignin/verifyStateproperly. -
Confirmed Entra ID app registration is correctly configured with Application ID URI, exposed API scope, and pre-authorized Teams/Copilot client IDs.
What We Understand
From the Microsoft documentation:
- SSO token exchange (
signin/tokenExchange) only works with Microsoft Entra ID as the OAuth service provider (source). - The
Token Exchange URLfield in Azure Bot OAuth Connection Settings is documented as "used for SSO in Microsoft Entra ID only" (source). - For third-party OAuth providers, the
tokenPostResource.sasUrlmechanism exists in the OAuthCard, but it appears to only be supported in custom canvas apps via Direct Line, not in the Teams/Copilot chat client (source).
Questions
-
Is there a planned improvement for the Copilot Chat client to automatically relay
signin/verifyStatefor third-party OAuth providers (similar to how Teams direct chat handles it), eliminating the need for users to manually copy/paste the magic code? -
Is there a supported pattern for Custom Engine Agents using
@microsoft/agents-hostingto achieve seamless authentication with a third-party OAuth provider in Copilot Chat without the magic code prompt? -
Does the
tokenPostResource.sasUrlmechanism work in the Teams/Copilot Chat client, or is it limited to custom canvas / Direct Line scenarios? If it works, what configuration is needed to enable it? -
As a workaround, would configuring an Entra ID OAuth connection (for SSO) alongside a separate third-party OAuth connection (for the actual API access) be a supported pattern? If so, are there any samples or documentation for this dual-connection approach?
Relevant Code
Auth handler configuration (config.ts):
return {
loopio: {
name: this.oauthConnectionName!,
text: this.authSignInText,
title: this.authSignInTitle,
enableSso: false, // Third-party OAuth — SSO token exchange only works with Entra ID
},
};Manifest (manifest.json):
{
"copilotAgents": {
"customEngineAgents": [{ "type": "bot", "id": "${{BOT_ID}}" }]
},
"bots": [{ "botId": "${{BOT_ID}}", "scopes": ["copilot", "personal", "team"] }],
"webApplicationInfo": {
"id": "${{BOT_ID}}",
"resource": "api://botid-${{BOT_ID}}"
}
}