Security: lock JsonWebToken trust-boundary contract#432
Merged
Conversation
lilyydu
approved these changes
May 22, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
This PR clarifies the Teams Python SDK’s layered JWT authentication model by documenting that JsonWebToken is a post-validation typed accessor and does not itself verify token signatures (validation happens at the HTTP boundary).
Changes:
- Expanded
JsonWebToken.__init__docstring to explicitly state it performs no signature/issuer/audience/expiry validation and must not be constructed from untrusted input. - Added inline commentary near
jwt.decode(... verify_signature=False)to reinforce the upstream trust-boundary contract.
corinagum
added a commit
to microsoft/teams.ts
that referenced
this pull request
May 26, 2026
## Summary Documents the layered authentication model the SDK uses for inbound JSON Web Tokens. TypeScript half of a 3-SDK PR set. ## Why Security scan finding "JsonWebToken No Signature Verification" flagged the `JsonWebToken` accessor class for decoding tokens without verifying signatures. A cross-SDK audit confirmed this is intentional architecture: signature verification runs at the HTTP boundary (`JwtValidator.validateAccessToken` in `packages/apps/src/middleware/auth/`), and the accessor exists as a typed view over already-validated payloads. Every consumer of decoded claims is downstream of a validator pass. This PR makes the architectural invariant explicit at the constructor site so future readers (and the scanner on its next pass) see the design intent locally. ## What Contract docstring at `JsonWebToken`'s constructor explaining that it performs no signature verification, where verification actually happens, and the rule that callers must not construct from raw network input. ## What this does not change - No runtime behavior change. No signature verification added or removed. - No API surface change. `JsonWebToken` keeps its current name and shape (verified public on `@microsoft/teams.api`, so a rename would have been breaking). - No effect on the activity pipeline. Bot Framework JWT validation continues to happen via `JwtValidator.validateAccessToken` exactly as before. ## Related PRs - Python: microsoft/teams.py#432 - .NET: microsoft/teams.net#517 - Documentation: microsoft/teams-sdk#2850
corinagum
added a commit
to microsoft/teams.net
that referenced
this pull request
May 26, 2026
…517) ## Summary Documents the layered authentication model the SDK uses for inbound JSON Web Tokens. .NET half of a 3-SDK PR set. ## Why Security scan finding "JsonWebToken No Signature Verification" flagged the `JsonWebToken` accessor class for using `JwtSecurityTokenHandler.ReadJwtToken()` (decode-only, no signature verification). A cross-SDK audit confirmed this is intentional architecture: signature verification runs at the ASP.NET Core JwtBearer middleware configured by `TokenValidator.ConfigureValidation` (`Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore/Extensions/TokenValidator.cs`), applied to endpoints via `.RequireAuthorization(...)`. The accessor exists as a typed view over already-validated payloads. Every consumer of decoded claims is downstream of either a JwtBearer validation or a trusted identity-infrastructure source. This PR makes the architectural invariant explicit at the constructor site so future readers (and the scanner on its next pass) see the design intent locally. ## What XML documentation on both `JsonWebToken` constructors explaining that they perform no signature verification, where verification actually happens, and the rule that callers must not construct from raw network input. ## Scope note: core/ (2.1) `core/` was audited separately and does not have an equivalent decode-only public accessor. Its inbound JWT validation is enforced at the middleware level with `ValidateIssuerSigningKey = true` and `RequireSignedTokens = true` hardcoded; there is no public API to misuse. The finding does not apply to `core/`. This PR scopes to `Libraries/` only. ## What this does not change - No runtime behavior change. No signature verification added or removed. - No API surface change. `JsonWebToken` keeps its current name (verified public in the packable `Microsoft.Teams.Api` assembly, including via `IContext<TActivity>.UserGraphToken` and `AspNetCorePlugin.ExtractToken()` return type; a rename would have been breaking). - No effect on the activity pipeline. JWT validation continues to happen via JwtBearer middleware exactly as before. ## Related PRs - TypeScript: microsoft/teams.ts#586 - Python: microsoft/teams.py#432 - Documentation: microsoft/teams-sdk#2850
corinagum
added a commit
to microsoft/teams-sdk
that referenced
this pull request
May 27, 2026
## Summary Adds a Trust Model page under Essentials → App Configuration documenting the layered authentication model the SDK uses for inbound JSON Web Tokens. ## Why A scanner flagged the SDK's `JsonWebToken` accessor class because it does not perform signature verification at the point of token parsing. A cross-SDK audit confirmed this is intentional architecture: signature verification runs at the HTTP boundary (via the activity pipeline's token validator), and the accessor class is a typed view over already-validated payloads. Every consumer of decoded claims is downstream of a validator pass. This page makes the architectural invariant explicit for SDK consumers, reviewers, and future contributors. ## What's covered - What the SDK validates automatically on `/api/messages` (signature, issuer, audience, lifetime, algorithm) - What downstream code can rely on (typed accessors over validated tokens) - How to add custom authentication to non-default surfaces (MCP, callbacks, webhooks) — references the `requireAuth` hook recently added in microsoft/teams.ts#540 / microsoft/teams.net#448 - Anti-patterns to avoid (constructing the accessor from untrusted input as a basis for authorization decisions) ## Build verified `npm run build` clean. ## Related PRs - TypeScript: microsoft/teams.ts#586 - Python: microsoft/teams.py#432 - .NET: microsoft/teams.net#517 --------- Co-authored-by: Copilot Autofix powered by AI <[email protected]>
7 tasks
corinagum
added a commit
that referenced
this pull request
May 27, 2026
## Summary Brings `origin/main` into `release` for the **2.0.12** release. **No carve-outs this time** — Quoted Replies (PR #321) is included. `version.json`: `2.0.11` → `2.0.12`. Aligns with teams.ts/teams.net cadence. ## What's in this release (delta from 2.0.11) **Features** - Quoted Replies & new quotes features (#321) — previously held back - SuggestedActionSubmitActivity for `suggestedAction/submit` invoke (#434) - Default targeted replies for targeted inbound messages (#439) - Reactions API marked GA (#427) — already shipped in 2.0.11 actually, ignore if duplicate - Prompt Preview support (#397) - Sample: opt targeted-messages into slash commands (#430) - Sample: a2a-in-teams (#401) - Sample: proactive message update (#405) - Allow custom HTTP client via `AppOptions` (#416) **Security & fixes** - Lock JsonWebToken trust-boundary contract (#432) - Bump starlette 1.0.0 -> 1.1.0 for PYSEC-2026-161 / BadHost (#441) - warn when bot starts without credentials (#435) - fix(apps): support AAD v1 issuers in Entra token validation (#422) - fix(apps): log inbound activities at info, warn on missing Authorization (#425) - fix(http-stream): wait for in-flight flush before sending final close (#419) - Mark reactions API as GA and fix sample remove flow (#427) - Revert serviceUrl allowlist (ADO 5310460) (#415) - Route `app.get_app_graph` + `ctx.*_graph` to sovereign endpoints via `cloud.graph_scope` (#402) **Deprecations / package changes** - Remove ai, openai, mcpplugin, a2a, and devtools packages (#413) - Restore and deprecate devtools package (#410) - Deprecate ai, openai, mcpplugin, a2a packages (#406) - Add agent framework example, remove chatprompt/mcp client samples (#386) **Dependency bumps** - urllib3 2.6.3 → 2.7.0 (#426) - python-multipart 0.0.26 → 0.0.27 (#424) - microsoft-kiota-http 1.9.7 → 1.9.9 (#423) - idna 3.11 → 3.15 (#431) - starlette 1.0.0 → 1.1.0 (#441, security) - /examples/tab/Web: qs, postcss, uuid, follow-redirects bumps ## Quoted Replies inclusion notes - Teams client rendering is in-sync with the wire format as of 2026-05-06. - APX QR rollout completed: Public 2026-04-10, GCCH/DoD/Gallatin 2026-04-14. - Builder methods (`prepend_quote()`, `add_quote()`), `ctx.quote()`, and the quote-aware `ctx.reply()` behavior are all present in this release. - `examples/quoting` is included. ## Conflict resolution The 2.0.11 release branch had the QR-removed shape for four files; took `main`'s (QR-included) version for all of them: - `examples/targeted-messages/src/main.py` - `packages/api/src/microsoft_teams/api/activities/message/message.py` - `packages/apps/src/microsoft_teams/apps/routing/activity_context.py` - `packages/apps/tests/test_activity_context.py` `version.json` conflict resolved to `2.0.12`. ## Test plan - [x] `uv sync` clean - [x] `poe check` (ruff format + lint) — clean - [x] `poe test` — 609 passed - [x] `pyright` — 0 errors, 0 warnings - [ ] Pipeline build + test stages green on `release` after merge - [ ] Publish pipeline run with **Public** → ESRP approval → PyPI - [ ] `pip install microsoft-teams-apps==2.0.12` smoke install --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: Aamir Jawaid <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]> Co-authored-by: Shanmathi Mayuram Krithivasan <[email protected]>
singhk97
added a commit
to microsoft/teams.net
that referenced
this pull request
May 28, 2026
commit fc3aaaa893e8dc8579b4ba466641ce906b766977 Author: Mehak Bindra <[email protected]> Date: Wed May 27 16:47:13 2026 -0700 Simplify dependency management for TeamsBotApplication (#521) This pull request refactors the Teams bot application hosting model to simplify bot setup and handler registration, unify options management, and streamline dependency injection. Key changes include updating the `TeamsBotApplication` constructor and options pattern, consolidating handler registration into bot subclasses, and improving the `ApiClient` interface. The sample bots and tests are updated to reflect these changes. **TeamsBotApplication and Options Refactoring:** * The `TeamsBotApplication` constructor now takes an `ApiClient`, `IHttpContextAccessor`, a logger, and an optional `TeamsBotApplicationOptions`, consolidating the previously separate conversation and user token clients into the `ApiClient`. The options class now inherits from `BotApplicationOptions` for unified configuration. **Sample Bot Simplification:** * The ExtAIBot sample is refactored: handler registration is moved from a static extension method into the `ExtAIBotApp` class constructor, and the DI registration is updated to use the new hosting model. **ApiClient Interface Improvements:** * `ApiClient` now exposes `ConversationClient` and `UserTokenClient` as internal properties instead of private fields, improving testability and consistency. All constructors and copy methods are updated accordingly. **Configuration and Dependency Injection Updates:** * The Teams bot options now automatically set the `AppId` from the resolved bot configuration. The ExtAIBot sample's `appsettings.json` and DI registrations are updated to match the new options and Azure OpenAI configuration pattern. **Test and Code Cleanup:** * Unit tests are updated to use the new constructor patterns, and unnecessary project references are removed. --------- Co-authored-by: Copilot Autofix powered by AI <[email protected]> Co-authored-by: Rido <[email protected]> commit 80aa830d46099d0ea75b4845d4440d5910c9b542 Author: Rido <[email protected]> Date: Wed May 27 14:34:43 2026 -0700 Fix async anti-patterns across all library projects (#402) - **#396** - Fix sync-over-async blocking calls (`GetAwaiter().GetResult()`) by converting to proper `await` in `ApplicationBuilder.Functions`, `Stream`, `ChatPrompt.Errors`; add `ConfigureAwait(false)` to `ServiceCollection` DI factory - **#397** - Fix CancellationToken misuse: propagate tokens correctly in `OpenAIChatModel.Send`, `Context.Send`, `HttpClient.SendAsync`; add missing `CancellationToken` parameter to `IChatPlugin.OnBuildInstructions` - **#398** - Replace empty `catch { }` blocks with exception logging in `App.cs`, `Context.SignIn`, `McpClientPlugin` - **#399** - Add error handling to fire-and-forget `Flush()` calls in `AspNetCorePlugin.Stream` via `FlushSafe()` wrapper; replace `Task.Run(() => { })` with `Task.CompletedTask`; use `_ =` discard pattern in debounce extensions - **#400** - Add `ConfigureAwait(false)` to ~380 `await` calls across all library projects to prevent deadlocks and unnecessary context capture - **#401** - Replace `Task.Run` wrapping sync code with direct execution + `Task.CompletedTask` in `LocalStorage`; fix unsafe reflection-based `Task.Result` access in `MethodInfoExtensions` Fixes #396, #397, #398, #399, #400, #401 - [x] Solution builds with 0 errors - [x] All existing tests pass (122 Apps tests, 15 AspNetCore tests, 9 McpClient tests, 3 Graph tests) - [x] Verify streaming behavior works correctly with the new `EmitAsync` method on `IStream` - [x] Verify cancellation propagation works for OpenAI API calls - [x] Verify OAuth sign-in flow logs errors appropriately instead of silently swallowing 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]> Co-authored-by: Copilot <[email protected]> Co-authored-by: rido-min <[email protected]> commit db32621c33c32541440282437ab0b9f7e6504b19 Author: Corina <[email protected]> Date: Wed May 27 12:59:58 2026 -0700 Reject unauthenticated requests when no credentials are configured (#530) `AddTeamsTokenAuthentication` currently engages the `RequireAssertion(_ => true)` bypass policy whenever `skipAuth: true` is passed **or** the configured `ClientId` is empty. That means an empty `ClientId` silently disables auth for any deployment that forgot to set credentials, with no opt-in. This change splits the condition: `skipAuth: true` still bypasses, but a missing `ClientId` without `skipAuth` now fails closed (`RequireAssertion(_ => false)`). Callers that intentionally want unauthenticated local development pass `skipAuth: true` to `AddTeams(...)`. Aligns with the equivalent change in TypeScript (microsoft/teams.ts#506) and Python (microsoft/teams.py#360). - [ ] Existing test suite passes - [ ] Add a test asserting requests are rejected (401/403) when `ClientId` is empty and `skipAuth` is not set - [ ] Add a test asserting requests still bypass when `skipAuth: true` is explicitly passed with empty `ClientId` - [ ] Manual: run a sample with no credentials configured and confirm requests now fail closed unless `skipAuth: true` is set commit 3ddf9fa76ec1801a0e3ca312c6d9855879571ac1 Author: Kavin <[email protected]> Date: Wed May 27 15:56:07 2026 -0400 sync main with patches in releases/core (#505) applied some patches to releases/core to fix the released version. syncing main now. commit e975f15ad3b690524ba51d6d16962a8dbbb5efaa Author: Kavin <[email protected]> Date: Wed May 27 14:47:40 2026 -0400 feat: SuggestedActionSubmit handler for 2.1 (#528) Ports the `suggestedActions/submit` invoke support from Libraries/ (#464) to core/: - `InvokeNames.SuggestedActionSubmit` constant and `ActionType.Submit` - `OnSuggestedActionSubmit()` handler extension on `TeamsBotApplication` - `SuggestedActionBot` sample - Unit tests All new API surface marked `[Experimental("ExperimentalTeamsSuggestedAction")]`. - [x] `dotnet build core.slnx` — clean - [x] `dotnet test core.slnx` — 755/755 pass on both net8.0 and net10.0 - [x] E2E verified against Teams client <img width="671" height="289" alt="image" src="https://github.com/user-attachments/assets/2959f3c9-f194-4e1f-9e06-9cdf6bbb86d0" /> --------- Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]> Co-authored-by: Rido <[email protected]> commit 733a37f2b7310e6fd954187427f2af0e713dc286 Author: Corina <[email protected]> Date: Wed May 27 11:41:17 2026 -0700 feat: deprecate DevTools (Libraries 2.0) in favor of Microsoft 365 Agents Playground (#522) - **`[Obsolete]` on `DevToolsPlugin` and `AddTeamsDevTools()`** in `Microsoft.Teams.Plugins.AspNetCore.DevTools`. Consumers see CS0618 on their `.AddTeamsDevTools()` calls with a clear migration message. - **Add anonymous-mode startup warning** in `AddTeamsTokenAuthentication` when `Teams:ClientId` is empty. Customers running with no credentials get an explicit signal that their bot accepts unauthenticated requests on `/api/messages`. - **Remove `AddTeamsDevTools()`** and the DevTools `ProjectReference` from all 16 samples. The samples now demonstrate the SDK without DevTools; users should run Microsoft 365 Agents Playground for local testing. - **`PackageReleaseNotes` and `[DEPRECATED]`-prefixed `PackageDescription`** on the DevTools csproj so the deprecation metadata surfaces in NuGet package browsers. - **README banner** on the DevTools package pointing at Microsoft 365 Agents Playground. DevTools is being replaced by Microsoft 365 Agents Playground. The replacement is a standalone CLI tool; customers install it separately and run it alongside their bot. For the grace period, `DevToolsPlugin` keeps working but loudly signals its deprecation through `[Obsolete]`, package metadata, and the README. The deprecation message wording stays version-agnostic per team convention ("a later version", not a specific version number). - The DevTools library's own internal `DevToolsController` references `DevToolsPlugin` (by design). To avoid breaking its build under `TreatWarningsAsErrors=true`, the DevTools csproj adds `CS0618` to its `NoWarn` list. Consumer code outside the library still sees the warning. - Three samples (`Samples.AI`, `Samples.Cards`, `Samples.Dialogs`) were pulling `Microsoft.Teams.Plugins.AspNetCore` in transitively through DevTools. Each gets an explicit `ProjectReference` so they keep building. - The project-wide `CS0618` suppression in `Samples/Directory.Build.props` is removed now that no sample calls `AddTeamsDevTools()`. The warning is emitted inline in `AddTeamsTokenAuthentication` via a small helper that looks up the host's already-registered `ILoggerFactory` instance directly off the service collection, falling back to `NullLogger` if no factory is registered yet. This mirrors the `GetLoggerFromServices` helper in `core/src/Microsoft.Teams.Core/Hosting/AddBotApplicationExtensions.cs`. The pattern was chosen over two earlier iterations after review feedback: - A standalone `LoggerFactory.Create(b => b.AddConsole())` would force console output regardless of consumer logging configuration. - An `IHostedService` (one of the intermediate iterations) was structurally heavyweight for a single startup warning. The warning text says "No Teams:ClientId configured" rather than mirroring the `CLIENT_ID / CLIENT_SECRET / TENANT_ID` env-var phrasing used in teams.ts and teams.py, because the .NET SDK binds settings through the `Teams:*` configuration section. - [x] `dotnet build Microsoft.Teams.sln` (0 errors, 1 pre-existing warning on `Samples.Tab` unrelated to this change) - [x] Confirmed `DevToolsPlugin` and `AddTeamsDevTools()` emit CS0618 to external consumers when used - [x] Anonymous-mode warning verified to fire from the inline `ILogger` lookup path (helper returns the registered factory's logger when present) - [ ] Reviewer to spot-check one or two samples compile and run cleanly without DevTools The corresponding `nuget.org` deprecation flag should be set on `Microsoft.Teams.Plugins.AspNetCore.DevTools` after this ships, so consumers running `dotnet add package` see a deprecation banner. Tracked separately by the publishing engineer. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]> commit 763c2cf3c2405fce5db7765b35c0a09d3d398b28 Author: Corina <[email protected]> Date: Wed May 27 10:47:17 2026 -0700 ci: add merge_group trigger to Build & Test & Lint (#531) - Adds `merge_group:` to the `on:` triggers of `.github/workflows/build-test-lint.yml` so the workflow runs on `gh-readonly-queue/*` refs created by GitHub's merge queue. - No behavior change until a merge queue is enabled on the `main` ruleset; the trigger is dormant otherwise. - Prereq for turning on "Require merge queue" — without this, the required `Build & Test & Lint` check would never report on queued PRs and the queue would stall. - [x] Confirm CI still runs as expected on this PR (pull_request trigger unchanged) - [ ] After merge, enable "Require merge queue" on the `main` ruleset and verify the workflow fires against the queue's temporary refs Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]> commit 0fce0f91010f05e6e843920182e741b84c527cbd Author: Kavin <[email protected]> Date: Wed May 27 13:30:42 2026 -0400 feat: SuggestedActionSubmitActivity for suggestedActions/submit invoke (#464) Adds first-class support for the `suggestedAction/submit` invoke activity (the platform-side dispatch of an `Action.Submit` suggested-action click). - New typed activity `SuggestedActionSubmitActivity` and `OnSuggestedActionSubmit` route extension, modeled after `HandoffActivity` / `OnHandoff`. - New `Microsoft.Teams.Api.Cards.ActionType.Submit` value, so bots can construct outbound `suggestedActions.actions[]` chips with `type: "Action.Submit"`, `title`, and structured `value`. - All new public surface marked `[Experimental("ExperimentalTeamsSuggestedAction")]`. Internal references suppress via `#pragma`. - New `Samples.SuggestedAction` project demonstrates both directions: bot replies with Approve/Reject chips, then handles the resulting invoke. - [x] `dotnet build Microsoft.Teams.sln` — clean - [x] `dotnet test Microsoft.Teams.sln` — 1293/1293 pass on both `net8.0` and `net10.0`. Includes a wire-format test asserting the outgoing `suggestedActions.actions[].{type,title,value}` JSON matches the design spec. - [x] Verified end-to-end against the running sample: posted a synthesized invoke, confirmed typed dispatch into `SuggestedActionSubmitActivity` and that `activity.Value` round-trips as a `JsonElement`. - [x] Manual verification with a payload from the Teams chat client once the platform side ships. --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]> Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: Copilot Autofix powered by AI <[email protected]> commit c90350b892696836fbfd69ca336aa96d5c92e16c Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed May 27 10:25:51 2026 -0700 Bump qs from 6.15.1 to 6.15.2 in /Samples/Samples.Tab/Web (#524) Bumps [qs](https://github.com/ljharb/qs) from 6.15.1 to 6.15.2. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/ljharb/qs/blob/main/CHANGELOG.md">qs's changelog</a>.</em></p> <blockquote> <h2><strong>6.15.2</strong></h2> <ul> <li>[Fix] <code>stringify</code>: skip null/undefined entries in <code>arrayFormat: 'comma'</code> + <code>encodeValuesOnly</code> instead of crashing in <code>encoder</code></li> <li>[Fix] <code>stringify</code>: use configured <code>delimiter</code> after <code>charsetSentinel</code> (<a href="https://redirect.github.com/ljharb/qs/issues/555">#555</a>)</li> <li>[Fix] <code>stringify</code>: apply <code>formatter</code> to encoded key under <code>strictNullHandling</code> (<a href="https://redirect.github.com/ljharb/qs/issues/554">#554</a>)</li> <li>[Fix] <code>stringify</code>: skip null/undefined filter-array entries instead of crashing in <code>encoder</code> (<a href="https://redirect.github.com/ljharb/qs/issues/551">#551</a>)</li> <li>[Fix] <code>parse</code>: handle nested bracket groups and add regression tests (<a href="https://redirect.github.com/ljharb/qs/issues/530">#530</a>)</li> <li>[readme] fix grammar (<a href="https://redirect.github.com/ljharb/qs/issues/550">#550</a>)</li> <li>[Dev Deps] update <code>@ljharb/eslint-config</code></li> <li>[Tests] add regression tests for keys containing percent-encoded bracket text</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/ljharb/qs/commit/9aca4076fe788338c67cf7e115f0be6bc58d85a8"><code>9aca407</code></a> v6.15.2</li> <li><a href="https://github.com/ljharb/qs/commit/5e33d33447ed0bf1ddab9abc41d27dea4687d992"><code>5e33d33</code></a> [Dev Deps] update <code>@ljharb/eslint-config</code></li> <li><a href="https://github.com/ljharb/qs/commit/21f80b33e5c8b3f7eba1034fff0da4a4a37a1d41"><code>21f80b3</code></a> [Fix] <code>stringify</code>: skip null/undefined entries in <code>arrayFormat: 'comma'</code> + `e...</li> <li><a href="https://github.com/ljharb/qs/commit/a0a81ea2071acce3eff41a040f719ac8f5c4f64c"><code>a0a81ea</code></a> [Fix] <code>stringify</code>: use configured <code>delimiter</code> after <code>charsetSentinel</code></li> <li><a href="https://github.com/ljharb/qs/commit/e3062f78f5233b338ceeb8e8dfa5a07dea4b32a8"><code>e3062f7</code></a> [Fix] <code>stringify</code>: apply <code>formatter</code> to encoded key under <code>strictNullHandling</code></li> <li><a href="https://github.com/ljharb/qs/commit/0c180a40adb8c6703fffc85b2ff06ca209f5c1e0"><code>0c180a4</code></a> [Fix] <code>stringify</code>: skip null/undefined filter-array entries instead of crashi...</li> <li><a href="https://github.com/ljharb/qs/commit/3a8b94aec19bd664720f6f6b1e66c4a0dfe4b656"><code>3a8b94a</code></a> [Tests] add regression tests for keys containing percent-encoded bracket text</li> <li><a href="https://github.com/ljharb/qs/commit/96755abd357c0e534dd3442a84a04d08864bfe0d"><code>96755ab</code></a> [readme] fix grammar</li> <li><a href="https://github.com/ljharb/qs/commit/a419ce5bbfcdb98a299f1a0bb47ea055baef20e6"><code>a419ce5</code></a> [Fix] <code>parse</code>: handle nested bracket groups and add regression tests</li> <li>See full diff in <a href="https://github.com/ljharb/qs/compare/v6.15.1...v6.15.2">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/microsoft/teams.net/network/alerts). </details> Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kavin <[email protected]> commit e2f98f1d2472ee96733aa109e0d33532e82a77d2 Author: Rido <[email protected]> Date: Wed May 27 09:46:53 2026 -0700 Fix GetLoggerFromServices returning NullLogger during DI setup (#526) - **Fixed** `GetLoggerFromServices` always returning `NullLogger` because it only checked `ImplementationInstance` for `ILoggerFactory`, which is `null` in typical ASP.NET Core apps where `AddLogging()` registers via factory delegate. - **Extracted** a shared `ResolveFromServices<T>` helper that tries `ImplementationInstance` first, then falls back to a temporary `ServiceProvider` — unifying the pattern already used in `BotConfig.Resolve` for `IConfiguration`. - [ ] Verify DI setup logs (e.g. `InferringUserAssignedManagedIdentity`) now appear in configured logging providers - [ ] Verify `BotConfig.Resolve` still resolves `IConfiguration` correctly - [ ] Run existing integration/unit tests to confirm no regressions 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]> Co-authored-by: copilot-swe-agent[bot] <[email protected]> commit f065e0a2fc43586e8f4b811d71d825634f5bfd0f Author: Corina <[email protected]> Date: Wed May 27 09:37:53 2026 -0700 Security hardening: gate DevTools WebSocket behind same-origin check (#527) Replaces the DevTools WebSocket `WebSocketOptions.AllowedOrigins = { "*" }` policy with a same-origin middleware that rejects upgrades whose `Origin` header does not match the request `Host` (and rejects absent `Origin`). The DevTools UI is always loaded from the same origin as the bot server, so legitimate clients send an `Origin` matching `Host`. Allowing any origin permitted any web page open in the developer's browser during local dev to open `ws://localhost:<port>/devtools/sockets` and inject or sniff DevTools traffic. Same-origin policy closes this without affecting the DevTools UI's own use of the endpoint. - No public API change. - No behavior change for the DevTools UI in normal use (it always loads same-origin). - DevTools is already environment-guarded (cannot start in `Production`), so this change tightens dev-mode behavior only. The Origin check inspects the `Upgrade` and `Origin` request headers directly rather than using `context.WebSockets.IsWebSocketRequest`, so the middleware does not depend on `UseWebSockets()` having registered `IHttpWebSocketFeature` first. - Full solution `dotnet build` and `dotnet test -f net10.0` clean. - `Samples.Echo` with DevTools enabled: - Same-origin upgrade (`Origin: http://localhost:3978`) → 101 Switching Protocols - Cross-origin upgrade (`Origin: https://attacker.example`) → 403 Forbidden - Missing `Origin` → 403 Forbidden - Plain GET `/devtools/` → 200 (UI still serves) `core/` does not register a similar WebSocket origin policy; the equivalent DevTools surface there does not currently exist. This PR scopes to `Libraries/`. commit d5bc4f2e7528460891592b5bcf5e629cdee57a7b Author: Mehak Bindra <[email protected]> Date: Tue May 26 14:07:08 2026 -0700 Improvements to MCP Server Sample (#518) This pull request introduces several significant improvements to the MCP server sample, focusing on user search, adaptive card-based asks, and enhanced approval/reply handling. The most important changes include adding a `find_user` tool to search for users by name or email, switching the "ask" flow to use adaptive cards (allowing multiple outstanding asks per user), and introducing efficient wait-based APIs for replies and approvals. The changes also update the handling of user IDs to always use Azure AD object IDs, and update the documentation accordingly. **User Search and Identity Handling** * Added a new `GraphClient` class and dependency to enable searching for users in the tenant by partial name, email, or UPN, returning their Azure AD object IDs. This is exposed via the new `find_user` tool and associated models (`UserMatch`, `FindUserResult`). * All tools now use the Azure AD object ID (`userId`) for identifying users, and the documentation clarifies this. **Adaptive Card-based Ask Flow** * The `ask` tool now sends an adaptive card with a reply box to the user, allowing multiple outstanding asks per user (previously only one was allowed). The reply is handled via adaptive card action, and the old single-ask logic is removed. * Added a handler for the new "ask_reply" adaptive card action, updating the pending ask and unblocking any waiters. **Wait-based APIs for Replies and Approvals** * Added `wait_for_reply` and `wait_for_approval` APIs that block (with timeout) until a reply or approval decision is received, using `TaskCompletionSource` for efficient waiting. Manual polling APIs (`get_reply`, `get_approval`) remain for compatibility **Other Improvements** * Updated the README to document the new tools and clarify user ID usage. * Refactored internal state handling to support the new flows and concurrency model. These changes modernize the MCP sample, improve user experience, and enable more robust automation scenarios. commit 0cabd5fe0a13eb9638a77b3ee5984d052fae16c4 Author: Corina <[email protected]> Date: Tue May 26 10:27:41 2026 -0700 Security: lock JsonWebToken trust-boundary contract (#6 disposition) (#517) Documents the layered authentication model the SDK uses for inbound JSON Web Tokens. .NET half of a 3-SDK PR set. Security scan finding "JsonWebToken No Signature Verification" flagged the `JsonWebToken` accessor class for using `JwtSecurityTokenHandler.ReadJwtToken()` (decode-only, no signature verification). A cross-SDK audit confirmed this is intentional architecture: signature verification runs at the ASP.NET Core JwtBearer middleware configured by `TokenValidator.ConfigureValidation` (`Libraries/Microsoft.Teams.Plugins/Microsoft.Teams.Plugins.AspNetCore/Extensions/TokenValidator.cs`), applied to endpoints via `.RequireAuthorization(...)`. The accessor exists as a typed view over already-validated payloads. Every consumer of decoded claims is downstream of either a JwtBearer validation or a trusted identity-infrastructure source. This PR makes the architectural invariant explicit at the constructor site so future readers (and the scanner on its next pass) see the design intent locally. XML documentation on both `JsonWebToken` constructors explaining that they perform no signature verification, where verification actually happens, and the rule that callers must not construct from raw network input. `core/` was audited separately and does not have an equivalent decode-only public accessor. Its inbound JWT validation is enforced at the middleware level with `ValidateIssuerSigningKey = true` and `RequireSignedTokens = true` hardcoded; there is no public API to misuse. The finding does not apply to `core/`. This PR scopes to `Libraries/` only. - No runtime behavior change. No signature verification added or removed. - No API surface change. `JsonWebToken` keeps its current name (verified public in the packable `Microsoft.Teams.Api` assembly, including via `IContext<TActivity>.UserGraphToken` and `AspNetCorePlugin.ExtractToken()` return type; a rename would have been breaking). - No effect on the activity pipeline. JWT validation continues to happen via JwtBearer middleware exactly as before. - TypeScript: microsoft/teams.ts#586 - Python: microsoft/teams.py#432 - Documentation: microsoft/teams-sdk#2850 commit 37577ede8e0bfdd8e5b76b553e6fd1c409b3afdd Author: Rido <[email protected]> Date: Fri May 22 11:15:10 2026 -0700 Update README and icon for core packages (#520) Revise the README files to clarify the setup process for the Teams bot application and remove outdated OAuth scope references. This update enhances the documentation's accuracy and relevance. commit 8d6b4f151680cef16b0a14160132096bed16a177 Author: Mehak Bindra <[email protected]> Date: Fri May 22 09:20:22 2026 -0700 Deprecating Microsoft.Teams.AI and Microsoft.Teams.AI.Models.OpenAI (#519) This pull request deprecates both the `Microsoft.Teams.AI` and `Microsoft.Teams.AI.Models.OpenAI` libraries, signaling that they will be removed by the end of summer 2026. T The most important changes are: **Deprecation Annotations in Code:** * Added `[Obsolete("Microsoft.Teams.AI is deprecated and will be removed by end of summer 2026.")]` to all major public classes and interfaces in the `Microsoft.Teams.AI` library, including `ChatPluginAttribute`, `FunctionAttribute`, `ParamAttribute`, `PromptAttribute`, `BaseChatPlugin`, `IChatPlugin`, `IFunction`, `Function`, and `FunctionCollection`. * Added `[Obsolete("Microsoft.Teams.AI.Models.OpenAI is deprecated and will be removed by end of summer 2026.")]` to all major public classes in the `Microsoft.Teams.AI.Models.OpenAI` library, such as `OpenAIChatModel`, `OpenAIChatPrompt`, `SequenceBuilder`, `StreamingChatToolCallsBuilder`, `MessageExtensions`, and `OpenAIChatModel.Options`. **Project Metadata and Documentation:** * Updated the NuGet package description and tags in `Microsoft.Teams.AI.Models.OpenAI.csproj` to reflect deprecation and added a warning suppression for obsolete usage. * Added a prominent deprecation notice at the top of the `README.md` for `Microsoft.Teams.AI.Models.OpenAI`. **Attribute Classes:** * Deprecated all attribute classes in both `Microsoft.Teams.AI` and `Microsoft.Teams.AI.Models.OpenAI`, including nested attributes like `Prompt.DescriptionAttribute`, `Prompt.InstructionsAttribute`, `Prompt.NameAttribute`, and `Function.DescriptionAttribute`. These changes ensure that developers are clearly warned about the upcoming removal of these libraries and are discouraged from using them in new projects. commit 6f33abacc55fe7e8c03129b1bfe04117efa5e636 Author: Mehak Bindra <[email protected]> Date: Thu May 21 14:05:44 2026 -0700 address model gaps (#472) This pull request introduces several deprecations and minor API adjustments across the Microsoft Teams API codebase. The primary focus is on marking certain properties, methods, and types as obsolete (to be removed by end of summer 2026), particularly in activity and account-related classes. There are also corresponding updates to constructors, serialization logic, and method usages to ensure compatibility and suppress deprecation warnings where necessary. Additionally, some usage of deprecated fields is being removed from application code. **Deprecations and Obsolescence Markings** * Marked several properties and types as `[Obsolete]`, including `RelatesTo` in `Activity`, multiple properties in `MessageActivity` (such as `Speak`, `InputHint`, `Importance`, `Expiration`), the `Id` property in `Attachment`, and the entire `EndOfConversationActivity` and `EndOfConversationCode` classes. These are all scheduled for removal by end of summer 2026. [[1]](diffhunk://#diff-875c3804dbdc89735553c417d023929c307dcfbead113a1b7a1e47871cab636aR59-R62) [[2]](diffhunk://#diff-875c3804dbdc89735553c417d023929c307dcfbead113a1b7a1e47871cab636aR127-R132) [[3]](diffhunk://#diff-05c926d7e09179d91c9c54a68c6b5efffb854bfddb70b431df77d6b2d280c44dR26-R31) [[4]](diffhunk://#diff-05c926d7e09179d91c9c54a68c6b5efffb854bfddb70b431df77d6b2d280c44dR56) [[5]](diffhunk://#diff-05c926d7e09179d91c9c54a68c6b5efffb854bfddb70b431df77d6b2d280c44dR65) [[6]](diffhunk://#diff-9151c814fbd9c905d4ab694534593d3ea239d68233e09908d71cacb7e7ff8902R20) [[7]](diffhunk://#diff-5d3b4f7fef169802c636878afce22853b92fe74a13a0462ab4930fad2b4edaf8R16) [[8]](diffhunk://#diff-5d3b4f7fef169802c636878afce22853b92fe74a13a0462ab4930fad2b4edaf8R35) * Marked several properties in `ConversationClient.CreateRequest` as obsolete, including `IsGroup`, `Bot`, and `TopicName`. [[1]](diffhunk://#diff-aad328d6be5c2acc005e534ddc0a3aae3e50d04e088908e5dc1f24962eac2e57R72-R77) [[2]](diffhunk://#diff-aad328d6be5c2acc005e534ddc0a3aae3e50d04e088908e5dc1f24962eac2e57R86) * Marked the `DeleteAsync` method in `MemberClient` as obsolete. **Deprecation Handling and Suppression** * Added `#pragma warning disable/restore CS0618` blocks throughout the codebase to suppress deprecation warnings when accessing or using obsolete properties and types, especially for `RelatesTo` and `EndOfConversationActivity`. [[1]](diffhunk://#diff-875c3804dbdc89735553c417d023929c307dcfbead113a1b7a1e47871cab636aR182-R184) [[2]](diffhunk://#diff-875c3804dbdc89735553c417d023929c307dcfbead113a1b7a1e47871cab636aR490-R492) [[3]](diffhunk://#diff-7fa90c4296b48d7529f16099722140fbb80a6c32663ef8b0e3f34488cd90c4fbR30-R32) [[4]](diffhunk://#diff-920cb13ff64033134157a73545c9d9090b7704c37e6ec43f830a7de9decd1282R67-R69) [[5]](diffhunk://#diff-920cb13ff64033134157a73545c9d9090b7704c37e6ec43f830a7de9decd1282R125-R131) [[6]](diffhunk://#diff-c163f6c08b3d0e64812ff6b8d265a93e6080cf1b2e4a143a0783d4657684e035R4-R5) [[7]](diffhunk://#diff-05c926d7e09179d91c9c54a68c6b5efffb854bfddb70b431df77d6b2d280c44dR94-R108) [[8]](diffhunk://#diff-05c926d7e09179d91c9c54a68c6b5efffb854bfddb70b431df77d6b2d280c44dR136-R141) [[9]](diffhunk://#diff-05c926d7e09179d91c9c54a68c6b5efffb854bfddb70b431df77d6b2d280c44dR151-R156) [[10]](diffhunk://#diff-05c926d7e09179d91c9c54a68c6b5efffb854bfddb70b431df77d6b2d280c44dR249-R263) **API and Serialization Adjustments** * Updated JSON serialization/deserialization logic in `Activity.JsonConverter` to handle the obsolete `EndOfConversationActivity` while suppressing warnings. [[1]](diffhunk://#diff-920cb13ff64033134157a73545c9d9090b7704c37e6ec43f830a7de9decd1282R67-R69) [[2]](diffhunk://#diff-920cb13ff64033134157a73545c9d9090b7704c37e6ec43f830a7de9decd1282R125-R131) * Added a new `Type` property to the `Account` class to indicate account type (e.g., 'person', 'bot', 'channel'), primarily for mention entities. **Removal of Deprecated Usage in App Code** * Removed usage of deprecated fields (`Role`, `IsGroup`, `Bot`, `InputHint`, `RelatesTo`) from application-level code in `App.cs`, `FunctionContext.cs`, and `Context.SignIn.cs` to prepare for future removals and ensure cleaner API usage. [[1]](diffhunk://#diff-37dcc8bb9c3f222673c45d1b99f581b4018f0aa2f92b91892c34a8d26c09f480L198) [[2]](diffhunk://#diff-038090b4dce958c0e716f21cba9d4e6fc1cf9e6beb8a8ddee6f70b0b6a5e284cL77-L89) [[3]](diffhunk://#diff-e07011b4e8cd0d4623a33ceab9466457358d5c9dac2d863185cefe919d7a96a0L77) [[4]](diffhunk://#diff-e07011b4e8cd0d4623a33ceab9466457358d5c9dac2d863185cefe919d7a96a0L88-L89) [[5]](diffhunk://#diff-e07011b4e8cd0d4623a33ceab9466457358d5c9dac2d863185cefe919d7a96a0L104) [[6]](diffhunk://#diff-e07011b4e8cd0d4623a33ceab9466457358d5c9dac2d863185cefe919d7a96a0L140-L141) commit df0d514e94824b583cc9c2d8e51216f0c25bba75 Author: Corina <[email protected]> Date: Thu May 21 09:02:44 2026 -0700 Bump version to 2.0.8-preview (#512) - Bumps `version.json` from `2.0.7-preview.{height}` to `2.0.8-preview.{height}` post-2.0.7 release - [ ] Verify next CI build picks up `2.0.8-preview.x` version 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Sonnet 4.6 (1M context) <[email protected]> Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: singhk97 <[email protected]> commit 84d0348d3c3d29df4d4de0b7229bd690a8a52e8f Author: Mehak Bindra <[email protected]> Date: Thu May 21 07:19:48 2026 -0700 A2A Sample (#490) This pull request introduces a new sample bot, `A2ABot`, which demonstrates proactive user handoff between two Teams bots (e.g., Alice and Bob) using the A2A protocol and the A2A .NET SDK. The sample is fully implemented with configuration, code, and documentation, showing how two bots can hand off users to each other and proactively open direct conversations in Teams. The main themes of the changes are the addition of the A2ABot sample, implementation of A2A protocol logic, and comprehensive documentation. **Addition of A2ABot sample and project setup:** * Added new sample project `A2ABot` to the solution, including its own `.csproj` file with dependencies on A2A, Teams SDKs, and Azure OpenAI. [[1]](diffhunk://#diff-19ad97af5c1b7109a9c62f830310091f393489def210b9ec1ffce152b8bf958cR13) [[2]](diffhunk://#diff-3db91520bb40fce7b5a3be0d4c62ca24c6f2c65980dc6270e9f2876f271beadfR1-R26) * Created environment-specific configuration files (e.g., `appsettings.Alice.json`) for easy setup of multiple bot instances. **A2A protocol logic and Teams integration:** * Implemented outbound (`A2AClient.cs`) and inbound (`A2AServer.cs`) A2A handlers to support handoff between bots, including resolving peer AgentCards, sending and receiving handoff messages, and proactively opening 1:1 Teams conversations. [[1]](diffhunk://#diff-9d41f72056b2baf435a7454dcb006e5079e51414f2c17167cb88f8ce859b3649R1-R55) [[2]](diffhunk://#diff-1adf74a85a4cdc7172918b6c49c3e19594d1a6058f791bf63b7059d14a7547bdR1-R85) * Defined supporting types for A2A communication, such as `Config`, `HandoffMessage`, and `AgentCardFactory`. [[1]](diffhunk://#diff-6a29af170dfac36c617e5eab5d4d828a3c9734a8d4407b866aa08d770dca9c15R1-R13) [[2]](diffhunk://#diff-a6b8eb57329120a115be51c84a807c254a33cbc1116de05a07a7fa004961547cR1-R16) [[3]](diffhunk://#diff-405b712de415edd4ec33453a35f45254041503815277db27d9569875575939d2R1-R38) * Implemented the main agent logic (`Agent.cs`), including LLM integration, thread management, and tool for handing off users to peers. * Set up the ASP.NET Core entry point (`Program.cs`) to wire up the bot, A2A endpoints, Teams message handling, and configuration. **Documentation:** * Added a comprehensive `README.md` explaining the sample's architecture, flow, configuration, prerequisites, and caveats for running two bots that hand off users via A2A. commit 61b00815cba5bafba022d8beb032c8c3be91e90b Author: Corina <[email protected]> Date: Wed May 20 16:28:42 2026 -0700 Prompt Preview Support (core) follow-up: string overload + JsonContext (#506) Two small fixes responding to Copilot's post-merge review on #498, plus sample alignment with the public slash-commands spec. - **`Context.SendActivityAsync(string text, ...)` now routes through `SendActivityAsync(TeamsActivity, ...)`.** Previously the string overload built the reply directly and called `TeamsBotApplication.SendActivityAsync` itself, bypassing the typed overload's 1:1-chat guard and the reactive Prompt Preview auto-populate hook. The string overload now also preserves `TextFormat = TextFormats.Plain` so the wire payload doesn't silently flip to markdown for existing callers. - **`TargetedMessageInfoEntity` is registered in `TeamsActivityJsonContext`** alongside `QuotedReplyEntity`. Deserialization round-tripped today via reflection fallback, but the registration was missing and would have broken under Native AOT publish. - New tests in `PromptPreviewTests.cs` cover the string-overload paths; new `TargetedMessageInfoEntity_RoundTripsThroughSourceGenContext` in `TargetedMessageInfoEntityTests.cs` pins the JsonContext registration so a future removal would surface immediately. - **`TargetedMessages` sample improvements**: - New `manifest.json` opted into slash commands per the docs spec (microsoft/teams-sdk#2843, MicrosoftDocs/msteams-docs#14182): `bots[].supportsTargetedMessages: true` + `bots[].commandLists[].triggers: ["slash"]`. Uses `manifestVersion: "devPreview"` because those fields are only in the devPreview schema today. - New `README.md` documenting the commands, manifest configuration, and how slash commands surface as targeted-message activities. - New `test inbound` handler demonstrates `Activity.Recipient?.IsTargeted` inbound detection (the same signal slash commands arrive with). - [x] `dotnet build core.slnx` clean on net8.0 and net10.0 - [x] `dotnet test core.slnx` passes (358 tests: 216 Apps + 101 Core + 41 BotBuilder) - [x] `SendActivityAsync_StringOverload_AutoPopulatesTargetedMessageInfo_WhenInboundIsTargeted` exercises the auto-populate hook on the string overload path - [x] `SendActivityAsync_StringOverload_Succeeds_InPersonalChat` documents that the string overload cannot construct a targeted recipient and therefore can't trip the 1:1 guard - [x] `TargetedMessageInfoEntity_RoundTripsThroughSourceGenContext` exercises `TeamsActivityJsonContext.Default.TargetedMessageInfoEntity` (Native AOT regression guard) - [x] `TargetedMessages` sample `manifest.json` validates against the Teams devPreview schema (placeholder `YOUR_BOT_ID` excepted, matching peer-sample convention) - [x] Sample bot's `test inbound` handler verified live in Teams: broadcast branch fires when the inbound is not targeted (the targeted branch will fire once slash commands start delivering with `Recipient.IsTargeted = true`) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]> commit f663f43fac7c8794b658d4d984c82d33a9f56bf9 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed May 20 23:16:23 2026 +0000 Bump ghcr.io/devcontainers/features/docker-in-docker from 2.17.0 to 3.0.0 (#516) Bumps ghcr.io/devcontainers/features/docker-in-docker from 2.17.0 to 3.0.0. [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Rido <[email protected]> commit 5893bff7cbc39c507d9461303a15d6c6d0dd3ccc Author: Corina <[email protected]> Date: Wed May 20 15:59:05 2026 -0700 core: add sovereign cloud support via AzureAd configuration (#507) Enables sovereign cloud (GCC-High, DoD, China) Bot Framework token validation by making the three cloud-dependent values in `JwtExtensions` configurable, mirroring the `IConfiguration` pattern already used by `UserTokenClient`. Three new properties on `BotConfig`, populated by `BotConfig.Resolve`: | Property | Config key | Default | Purpose | |---|---|---|---| | `EntraInstance` | `AzureAd:Instance` | `https://login.microsoftonline.com/` | Entra login instance for validating Entra-issued tokens (standard Microsoft.Identity.Web key, stays in the AzureAd section) | | `OpenIdMetadataUrl` | `BotFramework:OpenIdMetadataUrl` | `https://login.botframework.com/v1/.well-known/openid-configuration` | Bot Framework OIDC metadata endpoint used to fetch signing keys for inbound BF tokens | | `BotTokenIssuer` | `BotFramework:BotTokenIssuer` | `https://api.botframework.com` | Expected `iss` claim on inbound Bot Framework tokens | Bot-Framework-specific keys live in a separate `BotFramework` configuration section so they are not conflated with MSAL's `AzureAd` section. `Instance` remains under `AzureAd` because it is a standard Microsoft.Identity.Web key. Each override is validated as an absolute URI in `BotConfig.Resolve`; malformed values throw `InvalidOperationException` with the `section:key` path so misconfiguration fails fast instead of deferring to a runtime JWT failure. `JwtExtensions.AddTeamsJwtBearer` resolves `BotConfig` once and uses these values in both the issuer-signing-key resolver (`ResolveSigningAuthority`) and the issuer validator (`ValidateTeamsIssuer`). When `IConfiguration` is not registered (manual-credentials callers on a plain `ServiceCollection`), all three fall back to the public-cloud defaults. ```json { "AzureAd": { "TenantId": "...", "ClientId": "...", "Instance": "https://login.microsoftonline.us/" }, "BotFramework": { "OpenIdMetadataUrl": "https://login.botframework.azure.us/v1/.well-known/openid-configuration", "BotTokenIssuer": "https://api.botframework.us" } } ``` - `Authority` fallback for `EntraInstance` is intentionally not implemented. `Instance` is the canonical Microsoft.Identity.Web field and matches the keys Microsoft Learn uses for sovereign cloud configuration. - `BotConfig` source formats other than the `AzureAd` schema are not extended in this PR. - v1.0 `sts.windows.net` issuer validation remains accepted (covers commercial v1.0 tokens). - [x] `dotnet build core/core.slnx` clean (0 warnings, 0 errors) - [x] `dotnet test core/test/Microsoft.Teams.Core.UnitTests` (130 passed) - [x] Default values returned when overrides absent - [x] Configured values used for sovereign US Gov and China clouds - [x] Sovereign BF tokens route to the configured `OpenIdMetadataUrl` for key resolution - [x] Malformed URI in any of the three keys throws `InvalidOperationException` with the section:key path - [x] BotFramework section is read independently of the AzureAd section name - [x] Manual `AddBotAuthentication(clientId, tenantId)` overload does not require `IConfiguration` 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]> Co-authored-by: Rido <[email protected]> commit 1b83226b8b32bbf6bbede21afbc0fd5fb6808c55 Author: Mehak Bindra <[email protected]> Date: Wed May 20 14:14:23 2026 -0700 Core/activity extensions (#515) This pull request primarily refactors and streamlines how activity entity extension methods are organized, accessed, and documented in the Teams SDK core. It consolidates and migrates extension methods for activities (such as quoting, citations, and targeted messages), updates the migration guides and breaking change documentation, and removes the obsolete `AllFeatures` sample. The changes also update sample usage to use the new builder and extension method patterns, and introduce new helper methods for entity access. **Refactoring and consolidation of activity entity extension methods:** * Removed `ActivityQuotedReplyExtensions.cs` and `ActivityTargetedMessageInfoExtensions.cs`, moving their logic into more appropriately named and organized extension classes (such as `MentionEntityExtensions`, `CitationEntityExtensions`, etc.), and updated usages throughout the codebase. [[1]](diffhunk://#diff-5b565cdafa365671ca7c917fabad6d126f7f290e010481b7e2b6404cd74a4cadL1-L82) [[2]](diffhunk://#diff-8bbc57126c4f493e1eac6296888b0b3df8441d36ad8d1784c63d339cdc742554L1-L66) [[3]](diffhunk://#diff-39b57f845e0f83ee2c8d332d8785f93c92128500aa0492ccc442916c8f0db84eR1-R55) [[4]](diffhunk://#diff-22cd31a51c97a37f8bf2cffb4c061f52cb71d0755523954f59cef55883c7d1ebL204-R204) * Introduced new extension methods and helpers for accessing entities (e.g., `GetMentions`, `GetQuotedMessages`, `GetCitation`, etc.) and updated documentation to reflect these changes. [[1]](diffhunk://#diff-8239e4655133747a84cff44bc0444f20907380d344b35e512d70a603ce1a3f8cL180-R198) [[2]](diffhunk://#diff-39b57f845e0f83ee2c8d332d8785f93c92128500aa0492ccc442916c8f0db84eR1-R55) **Sample and usage updates:** * Updated all sample code (`Quoting`, `TeamsBot`) to use the new builder pattern and extension methods for adding quotes and citations, replacing old direct usage of message entities. [[1]](diffhunk://#diff-bd68ef7114703a580af98ae0c650b648dd74909fea6665395b98516956157448L48-R57) [[2]](diffhunk://#diff-bd68ef7114703a580af98ae0c650b648dd74909fea6665395b98516956157448L69-R77) [[3]](diffhunk://#diff-bd68ef7114703a580af98ae0c650b648dd74909fea6665395b98516956157448L102) [[4]](diffhunk://#diff-691809f7a90c5bda6ee5e4335c2c393864a32101545fb0b35c24bc659623361bL113-R132) * Removed the obsolete `AllFeatures` sample project and its related files. [[1]](diffhunk://#diff-c6d02c3a9a28c1afb6380d7f24485630894a3488bd6529f31cca342583be4897L1-L13) [[2]](diffhunk://#diff-7c963be5ba9074d831ef650e68af0360787eb197181c39a12d0661a92c62fbc1L1-L6) [[3]](diffhunk://#diff-166193a2c938377ccf1794248deeb2df8cfafeb883aa6581b316b3fa9e361cdcL1-L28) [[4]](diffhunk://#diff-ea0a609f6688222857d8302f64ba6a7d75aa4ffb1f9a70588b86caacd73dbad1L1-L9) **Documentation improvements:** * Updated the migration guide and breaking changes documentation to clarify the new patterns for activity entity access and construction, including extension method availability and builder usage. [[1]](diffhunk://#diff-8239e4655133747a84cff44bc0444f20907380d344b35e512d70a603ce1a3f8cL180-R198) [[2]](diffhunk://#diff-8239e4655133747a84cff44bc0444f20907380d344b35e512d70a603ce1a3f8cL266-R300) [[3]](diffhunk://#diff-54d546db32e8cde5d5c68b70319c4c57859aaae3b11df4da4b699d389c153644L396-R418) **Project and solution cleanup:** * Removed the `docs/Architecture.md` file from the solution, likely as part of documentation consolidation. commit 731d4bbf10324dc766a35201fd07dd32524e8a7a Author: Kavin <[email protected]> Date: Fri May 15 15:02:17 2026 -0400 Make core packages compliant with Microsoft NuGet authoring requirements (#513) - Brings the three core packages (`Microsoft.Teams.Core`, `Microsoft.Teams.Apps`, `Microsoft.Teams.Apps.BotBuilder`) into compliance with the Microsoft NuGet package authoring requirements. - Adds `PackageProjectUrl`, fixes a broken `PackageIcon` packing path in `core/src/Directory.Build.props`, renames `Description` → `PackageDescription`, adds `PackageTags`, and adds MIT license/copyright header comments to each csproj. - Also bumps `versionHeightOffset` in `core/version.json` and `core/src/Microsoft.Teams.Apps/version.json`. | Requirement | Before | After | | --- | --- | --- | | `PackageProjectUrl` | missing | `https://microsoft.github.io/teams-sdk` | | `PackageIcon` packing | broken path (`(MSBuildThisFileDirectory)../../../../bot_icon.png`) | `$(MSBuildThisFileDirectory)../bot_icon.png` | | `PackageDescription` | used `Description` | `PackageDescription` | | `PackageTags` | missing | `microsoft;teams;msteams;copilot;ai;adaptive-cards;apps;bots` | | License header | missing | MIT header comment in each csproj | - `core/bot_icon.png` is 75x75; the authoring spec recommends 100x100 (with clean downscaling to 32/48/64/128). - Strong-name signing (`SignAssembly` + `key.snk`) — not adopted in core yet, matches existing core stance. - [ ] `dotnet pack` the three core projects locally and inspect the produced `.nupkg` to confirm `bot_icon.png` and `README.md` are packed at the root and the metadata fields render correctly. - [ ] Verify the icon shows up on the nuget.org preview / `nuget.exe verify` step in CI. - [ ] CI build passes on the branch. --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]> commit 1ed9636ef8bc1a6a74e3de106baeaabde09cee24 Author: Mehak Bindra <[email protected]> Date: Fri May 15 11:14:14 2026 -0700 Add AI/MCP Client example (#486) This pull request introduces a new sample Teams bot, `ExtAIBot`, that demonstrates the integration of Microsoft.Extensions.AI with Azure OpenAI and the Model Context Protocol (MCP) for advanced conversational capabilities. The main changes include the implementation of the bot’s core logic, support for streaming responses, per-conversation memory, local and remote tool invocation, and feedback handling. Additionally, supporting infrastructure and documentation are provided. **Key new features and infrastructure:** * Added the complete `ExtAIBot` sample including core files: `Agent.cs` (conversation logic with streaming, memory, and tool invocation), `LocalTools.cs` (local AI tool definitions), `McpTools.cs` (MCP client and tool wrapping for citations), and `CitationCollector.cs` (parsing and accumulating citations for Teams messages). * Implemented `Program.cs` to wire up the Teams bot, register message and feedback handlers, and delegate AI execution to the `Agent`. * Added support for Teams feedback via new invoke names and value types, including `message/fetchTask` and associated data classes in the Teams SDK. * Implemented feedback collection and UI in the sample bot, including Adaptive Card generation for feedback and console logging of user input. * Added `appsettings.json` and updated the project file to include all necessary dependencies and references for running the sample. * Provided a comprehensive `README.md` with setup instructions, architecture diagrams, and example interactions to help users understand and run the sample. commit a987b1453c73b9554de50e4e1a9452f14192dc40 Author: Corina <[email protected]> Date: Thu May 14 13:51:26 2026 -0700 Mark reactions API as GA across Libraries and core (#509) Removes the `[Experimental("ExperimentalTeamsReactions")]` attributes from `ReactionClient`, `ReactionType`, `Reaction`, and the `Reactions` property on `ConversationApiClient`/`ConversationClient`, across both `Libraries/` and `core/`. Also removes the corresponding `#pragma warning disable/restore` blocks and `NoWarn` entries in test and sample `.csproj` files. The reactions feature is in sync across all three SDKs and the Teams service — no longer preview. **Attributes removed (5):** - `Libraries/Microsoft.Teams.Api/Clients/ReactionClient.cs` - `Libraries/Microsoft.Teams.Api/Messages/Reaction.cs` (`ReactionType` and `Reaction`) - `core/src/Microsoft.Teams.Apps/Api/Clients/ReactionClient.cs` - `core/src/Microsoft.Teams.Apps/Api/Clients/ConversationApiClient.cs` (`Reactions` property) **Suppressions removed (8 inline pragma locations + 5 NoWarn entries in .csproj files):** - `Libraries/Microsoft.Teams.Api/Clients/ConversationClient.cs` (5 sites) - `Libraries/Microsoft.Teams.Api/Messages/Message.cs` - `Libraries/Microsoft.Teams.Api/Activities/Message/MessageReactionActivity.cs` (file-level) - `core/src/Microsoft.Teams.Apps/Api/Clients/ConversationApiClient.cs` - `.csproj` NoWarn: `Samples/Samples.Reactions`, `core/test/IntegrationTests`, `core/samples/TeamsBot`, `Tests/Microsoft.Teams.Api.Tests`, `Tests/Microsoft.Teams.Apps.Tests` The `Samples.Reactions/Program.cs` already demonstrates add → wait → delete cycle, so no sample change is needed here. Part of the cross-SDK Reactions-GA pass. Sibling PRs: - microsoft/teams.ts — Mark reactions API as GA - microsoft/teams.py — Mark reactions API as GA - microsoft/teams-sdk — drop .NET opt-in tip from the reactions guide - [x] `dotnet build Microsoft.Teams.sln --configuration Release` — 0 errors - [x] `dotnet build core.slnx --configuration Release` — 0 errors - [x] `dotnet test Microsoft.Teams.sln` — all suites pass (Apps 146+146, Api 422, Common 63, AI 17, Graph 3, McpClient 9, AspNetCore 25+25 net8/net10) - [x] `dotnet test core.slnx` — all suites pass (Apps.UnitTests 213+213, Core.UnitTests 101+101, BotBuilder.UnitTests 41) No `version.json` change in this PR. Bump happens as part of the release flow per RELEASE.md. 🤖 Generated with [Claude Code](https://claude.com/claude-code) commit 475b11ff9640147b4b19450ae952388cef6f6176 Author: Corina <[email protected]> Date: Wed May 13 12:47:34 2026 -0700 Prompt Preview Support (core) (#498) Prompt Preview lets a bot reference the original targeted message in its reply so Teams can render a collapsible preview of the user's prompt above the response. This brings the feature to `core/` with parity to the Libraries implementation in #433. - New `TargetedMessageInfoEntity` in `Microsoft.Teams.Apps.Schema.Entities` carrying the `messageId` of the targeted prompt - `AddTargetedMessageInfo` extension on `MessageActivity` and `WithTargetedMessageInfo` on `TeamsActivityBuilder` for proactive use. Both strip existing `quotedReply` entities and matching `<quoted messageId="..."/>` placeholders to prevent collision with Quoted Replies - `Context.SendActivityAsync` auto-populates the entity in the reactive flow when the inbound activity's recipient was marked targeted - Personal-chat guard in `Context.SendActivityAsync` throws `InvalidOperationException` when a targeted send is attempted in a 1:1 conversation (matches Libraries; teams.ts and teams.py have no guard) - `ConversationAccount.IsTargeted`, `WithRecipient(account, bool isTargeted)`, the new entity, and the new builder/extension methods are marked `[Experimental("ExperimentalTeamsTargeted")]`, matching the existing diagnostic on `ActivityClient.CreateTargetedAsync` etc. - New `TargetedMessages` sample bot demonstrating `test send`, `test update`, `test delete`, reactive `summarize`, and `test manual` - Setter on `ConversationAccount.IsTargeted` stays `public set` (not mirroring the Libraries `internal set` outlier) to match the uniform setter pattern across `core/` schema types. - The `MessageId` getter on `TargetedMessageInfoEntity` throws `InvalidOperationException` with a descriptive message if accessed after deserialization from JSON that omitted the `messageId` field. `required` enforces initialization in C# code but does not gate the underlying extension-properties dictionary path. - [x] `dotnet build` in `core/` is clean on net8.0 and net10.0 - [x] `dotnet test` in `core/` passes (340 unit tests: 207 Apps + 92 Core + 41 BotBuilder) - [x] Run the new `TargetedMessages` sample and confirm `test send` / `test update` / `test delete` render correctly in a Teams group chat - [x] Confirm `test send` from a personal chat surfaces the 1:1 `InvalidOperationException` 🤖 Generated with [Claude Code](https://claude.com/claude-code) commit b10c0fef711973fff199283cd9a3f9b9cd17eb78 Author: Kavin <[email protected]> Date: Wed May 13 14:56:28 2026 -0400 Switch Microsoft.Teams.Apps to 2.1.0-preview; bump core versionHeightOffset to -3 (#504) - Change `Microsoft.Teams.Apps` prerelease tag from `alpha` to `preview` (`2.1.0-alpha.{height}` → `2.1.0-preview.{height}`) so we move out of the burned `2.1.0-alpha-*` version namespace on the feed. - Remove the now-unneeded `versionHeightOffset` from `core/src/Microsoft.Teams.Apps/version.json` (the prerelease label change starts the height counter on a fresh namespace). - Bump `versionHeightOffset` from `-2` to `-3` in `core/version.json` to keep Core/BotBuilder versions where intended. - [x] Verify `nbgv get-version` on `releases/core` after merge produces `2.1.0-preview-0001` (or expected) for `Microsoft.Teams.Apps`. - [x] Verify Core/BotBuilder package versions are unchanged or as intended after the `-3` offset. - [x] Verify CI publishes the package successfully (no 409 conflict on the new version). commit 3307d38daa28c1cc8ab30472d519b914e2199590 Author: Corina <[email protected]> Date: Wed May 13 11:41:19 2026 -0700 Add proactive threading helpers to core (port of #425) (#489) - Adds `Microsoft.Teams.Core.Schema.ConversationExtensions` with a `ThreadId(this Conversation)` extension method and a `ToThreadedConversationId(conversationId, messageId)` static validator (rejects non-numeric / zero `messageId`, strips any existing `;messageid=` suffix). Ported from `Libraries/Microsoft.Teams.Api/Conversation.cs`, where they live as instance/static members on `Conversation`; on core they live as a separate extension class so `Conversation` stays a pure POCO. - Replaces the inline `$"{conversationId};messageid={messageId}"` interpolation in proactive `TeamsBotApplication.ReplyAsync` with the validating helper. - Adds `core/samples/Threading/` modeled on `Samples/Samples.Threading/` to exercise reactive (`context.ReplyAsync` / `context.SendActivityAsync`) and proactive (`teamsApp.ReplyAsync` / `ConversationExtensions.ToThreadedConversationId` + `teamsApp.SendAsync`) paths. - Includes #493 (Rido), stacked on this PR: adds `Async`-suffixed methods to `Context` (`SendAsync`, `ReplyAsync`, `TypingAsync`, `SignInAsync`, `SignOutAsync`) and `TeamsBotApplication` (`SendAsync`, `ReplyAsync`) with the original names kept as backward-compat redirects; proactive `Send`/`Reply` accept an optional `AgenticIdentity?` for user-delegated token acquisition. - **`Context.ReplyAsync`** inherits the post-QR (PR #477) behavior on `main`: delegates to `Quote(Activity.Id, ...)` when the inbound activity has an id, producing a `<blockquote>`-rendered quoted reply. This PR doesn't change that delegation. - **Personal / 1:1 chats**: `test proactive` and `test manual` currently fail at the service with `BadArgument: Failed to decrypt conversation id` until the relevant ECS rollout completes. Channel scopes work today. `core/samples/Threading/README.md` documents this caveat. - [x] Unit: 12 `ConversationTests` (validator + `ThreadId` extension method) - [x] Unit: 3 `TeamsBotApplicationTests` (validator propagates from proactive `ReplyAsync`) - [x] Local CI: core-ci pipeline (325 tests on net8.0 + net10.0) + root build-test-lint / ci.yaml (813 tests + `dotnet pack`); 0 errors - [x] E2E in Teams: 6 turns covering `test reply`, `test send`, `test proactive`, `test manual`, `help` across an existing thread, a new thread, and channel root — all returned 201 with correct routing (`;messageid=<rootId>` preserved/created appropriately, `ReplyToId` set on reactive paths only) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Rido <[email protected]> Co-authored-by: Claude Opu…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Documents the layered authentication model the SDK uses for inbound JSON Web Tokens. Python half of a 3-SDK PR set.
Why
Security scan finding "JsonWebToken No Signature Verification" flagged the
JsonWebTokenaccessor class for decoding tokens without verifying signatures (usesverify_signature=False). A cross-SDK audit confirmed this is intentional architecture: signature verification runs at the HTTP boundary inTokenValidator.validate_token(packages/apps/src/microsoft_teams/apps/auth/token_validator.py), and the accessor exists as a typed view over already-validated payloads. Every consumer of decoded claims is downstream of a validator pass.This PR makes the architectural invariant explicit at the constructor site so future readers (and the scanner on its next pass) see the design intent locally.
What
Contract docstring at
JsonWebToken.__init__explaining that it performs no signature verification, where verification actually happens, and the rule that callers must not construct from raw network input.What this does not change
JsonWebTokenkeeps its current name (verified public onmicrosoft_teams.api, so a rename would have been breaking).TokenValidator.validate_tokenexactly as before.Related PRs