Skip to content

Add conditions to choose ConnectorClient scope#962

Draft
sw-joelmut wants to merge 5 commits into
mainfrom
southworks/add/connector-scope-issuers
Draft

Add conditions to choose ConnectorClient scope#962
sw-joelmut wants to merge 5 commits into
mainfrom
southworks/add/connector-scope-issuers

Conversation

@sw-joelmut

Copy link
Copy Markdown
Collaborator

Fixes #934

Description

This PR adds a condition to only use the azp and appid JWT identity values when the Activity.recipient.role is Skill, otherwise will resolve api.botframework.com as scope.

Testing

The following images show the Agent to Agent operations using MSTeams and WebChat
image
image

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a bug where TeamsInfo.getMember returns 401 errors when called from incoming webhooks. The issue occurred because the connector client scope was incorrectly derived from the incoming JWT's azp/appid claims instead of using the standard Bot Framework API scope.

Changes:

  • Added logic to conditionally select the connector client authentication scope based on the recipient role
  • Scope now defaults to https://api.botframework.com for non-Skill scenarios
  • Scope uses azp/appid only when communicating back to another agent (Skill role)

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
packages/agents-hosting/src/cloudAdapter.ts Extracted scope resolution logic into a new resolveConnectorScope method that checks recipient role before using azp/appid claims
packages/agents-hosting/test/hosting/adapter/cloudAdapter.test.ts Added three test cases to verify scope resolution for Skill and non-Skill scenarios

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


// ABS tokens will not have an azp/appid so use the botframework scope.
// Otherwise use the appId. This will happen when communicating back to another agent.
if (activity.recipient?.role === RoleTypes.Skill) {

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using case-insensitive comparison for consistency with other role checks in the same method (lines 143 and 151) which use .toLowerCase() for AgenticIdentity and AgenticUser. Since activity.recipient.role can be a string (as defined in ChannelAccount interface), and the Activity.isAgenticRequest() method uses case-insensitive comparison, using strict equality here could cause the condition to fail if the role string has different casing.

Consider changing to: if (activity.recipient?.role?.toLowerCase() === RoleTypes.Skill.toLowerCase())

Suggested change
if (activity.recipient?.role === RoleTypes.Skill) {
if (activity.recipient?.role?.toLowerCase() === RoleTypes.Skill.toLowerCase()) {

Copilot uses AI. Check for mistakes.
Comment thread packages/agents-hosting/test/hosting/adapter/cloudAdapter.test.ts
@sw-joelmut sw-joelmut marked this pull request as draft March 5, 2026 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] TeamsInfo.getMember returns 401 on incoming webhook

3 participants