Skip to content

feat(teams): forward a custom token factory to the Teams SDK - #732

Merged
bensabic merged 2 commits into
vercel:mainfrom
CamdenA21:feat/teams-token-passthrough
Jul 22, 2026
Merged

bensabic merged 2 commits into
vercel:mainfrom
CamdenA21:feat/teams-token-passthrough

Conversation

@CamdenA21

Copy link
Copy Markdown
Contributor

Summary

TeamsAdapterConfig never forwards a token field through to the underlying @microsoft/teams.apps AppOptions.token, even though the Teams SDK already supports it as a genuine "bring your own credentials" escape hatch (TokenCredentials['token']).

The only non-secret auth path currently exposed is federated, which maps to managedIdentityClientId and only resolves via Azure-native managed-identity sources (IMDS, AppService, CloudShell, MachineLearning, ServiceFabric). That's unreachable from serverless/edge runtimes (e.g. Vercel) that can't hit Azure IMDS but still need to mint access tokens through an external mechanism (e.g. a workload-identity federation bridge exchanging a platform-native OIDC token for an Azure AD token).

We've been carrying a local patch on @chat-adapter/teams doing exactly this forwarding to unblock a production Teams bot running on Vercel with a user-assigned managed identity. Opening this as a proper PR instead of staying on the patch indefinitely.

Changes

  • TeamsAdapterConfig.token?: (scope: string | string[], tenantId?: string) => string | Promise<string> — matches TokenCredentials['token']'s real signature.
  • toAppOptions forwards config.token straight through.
  • clientSecret resolution now also short-circuits when token is provided (alongside the existing federated check) — TokenManager.initializeCredentials checks clientId && clientSecret before clientId && token, so a stray appPassword/TEAMS_APP_PASSWORD would otherwise silently win over an explicitly configured token factory.
  • Unit tests in config.test.ts and a createTeamsAdapter factory test in index.test.ts.
  • Docs: added the token config option and a third "Authentication methods" example in apps/docs/content/adapters/official/teams.mdx.
  • Changeset (@chat-adapter/teams: minor).

Test plan

  • pnpm --filter @chat-adapter/teams test — 232/232 passing (including 4 new tests)
  • pnpm --filter @chat-adapter/teams typecheck — clean
  • pnpm konsistent — no violations
  • pnpm check — clean
  • pnpm knip — no new findings

@CamdenA21
CamdenA21 requested a review from a team as a code owner July 21, 2026 23:45
@vercel

vercel Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Someone is attempting to deploy a commit to the Vercel Team on Vercel.

A member of the Team first needs to authorize it.

TeamsAdapterConfig never forwarded a token field to the underlying
@microsoft/teams.apps AppOptions.token, even though the Teams SDK
already supports it as a "bring your own credentials" escape hatch
(TokenCredentials['token']). The only non-secret auth path exposed
was `federated`, which maps to managedIdentityClientId and only
resolves via Azure-native managed-identity sources (IMDS, AppService,
etc.) - unreachable from platforms like Vercel that can't reach Azure
IMDS but still need to mint access tokens through an external
mechanism (e.g. a workload-identity federation bridge).

Add `token` to TeamsAdapterConfig and forward it in toAppOptions,
matching the real TokenCredentials['token'] signature. Also omit
clientSecret when a token factory is configured - TokenManager checks
clientId+clientSecret before clientId+token, so a stray client-secret
env var would otherwise silently override the token factory.

Signed-off-by: CamdenA21 <camden@sandstone.ai>
@CamdenA21
CamdenA21 force-pushed the feat/teams-token-passthrough branch from e6169bd to ee11a86 Compare July 21, 2026 23:56
… cover env-var path in tests

- Note in the token JSDoc and docs that the Teams SDK prefers a generic
  CLIENT_SECRET env var over the token factory
- Replace the unenforced "exactly one auth method" doc claim with the
  actual precedence (token > federated > appPassword)
- Mention token in the certificate-auth error message
- Add a config test covering TEAMS_APP_PASSWORD being ignored when a
  token factory is provided
@bensabic
bensabic merged commit e06b4b6 into vercel:main Jul 22, 2026
12 of 14 checks passed
patrick-chinchill added a commit to Chinchill-AI/chat-sdk-python that referenced this pull request Sep 30, 2026
…ereign allowlists (#221)

Teams auth extension points: a custom token factory that beats every client-secret source, a webhook_verifier run on the exact raw body before parsing (replacing SDK JWT validation), a callable app_id resolved once in initialize(), and sovereign-cloud service-URL/Graph host allowlists.
Upstream commits ported: e06b4b60 (vercel/chat#732, chat@4.35.0), portable parts of 139d337e (vercel/chat#930, chat@4.41.0; Vercel Connect N/A), Teams part of 7609d8f6 (vercel/chat#876, chat@4.40.0).
Divergences: App subclass enforces token-factory precedence over CLIENT_SECRET (Python SDK credential order); ValueError instead of TeamsApiError for untrusted URLs; broader wildcard service-URL allowlist kept. Merged with #250: in verifier mode the Bot Framework issuer pre-check is bypassed, as upstream.
Consumer impact: all new options are opt-in; an empty webhook body now returns 400 (was parsed as {}).
Closes #221
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.

2 participants