Skip to content

Tighten AdditionalAllowedDomains API contract#450

Draft
corinagum wants to merge 2 commits intomainfrom
cg/fix-allowlist-plumbing-net
Draft

Tighten AdditionalAllowedDomains API contract#450
corinagum wants to merge 2 commits intomainfrom
cg/fix-allowlist-plumbing-net

Conversation

@corinagum
Copy link
Copy Markdown
Collaborator

@corinagum corinagum commented Apr 24, 2026

Follow-up to the allowlist feature (shipped via #418). No runtime behavior change for correct callers. Adds hardening informed by review feedback on the sibling Python PR (microsoft/teams.py#404):

  1. Docstring clarity. AppOptions.AdditionalAllowedDomains XML doc now documents that entries must be bare hostnames matched exactly (case-insensitive); wildcard patterns like "*.example.com", URL suffixes, and full URLs are NOT supported. ["*"] is the sole wildcard, used as a disable-validation sentinel.
  2. Defensive copy. App no longer stores the caller's IEnumerable<string> by reference. A post-construction mutation of the collection would previously have changed validator behavior at runtime; now it is isolated.
  3. Tests verifying the new contract: lazy enumerable materialization, null input, empty input.

Copilot AI review requested due to automatic review settings April 24, 2026 22:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 hardens the AdditionalAllowedDomains allowlist plumbing in Microsoft.Teams.Apps by clarifying the API contract and preventing post-construction mutation of caller-provided domain lists from affecting service URL validation behavior.

Changes:

  • Clarifies AppOptions.AdditionalAllowedDomains documentation (hostnames only; ["*"] disables validation).
  • Makes App defensively materialize/copy AdditionalAllowedDomains at construction time.
  • Adds unit tests to guard against regressions involving mutable/lazy enumerables.

Reviewed changes

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

File Description
Tests/Microsoft.Teams.Apps.Tests/AppTests.cs Adds tests asserting AdditionalAllowedDomains is materialized/defensively copied.
Libraries/Microsoft.Teams.Apps/AppOptions.cs Updates XML docs for AdditionalAllowedDomains contract and sentinel behavior.
Libraries/Microsoft.Teams.Apps/App.cs Changes internal storage to a materialized list via ToList() to prevent caller-side mutations.

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

Comment thread Libraries/Microsoft.Teams.Apps/AppOptions.cs
Comment thread Tests/Microsoft.Teams.Apps.Tests/AppTests.cs Outdated
Comment thread Libraries/Microsoft.Teams.Apps/AppOptions.cs
Comment thread Libraries/Microsoft.Teams.Apps/AppOptions.cs
@corinagum corinagum marked this pull request as draft April 28, 2026 18:54
corinagum added a commit that referenced this pull request Apr 28, 2026
## Summary

Reverting the serviceUrl allowlist defense-in-depth feature before
public release. Open design questions on the work item (default
sovereign cloud domains, narrowing of `*.botframework.com`, applying to
proactive `ConversationReference`s, consultation with APX) should be
resolved before this becomes part of the public API surface.

This feature has not shipped in any release. Removing the public
`AdditionalAllowedDomains` option is a breaking change for anyone
building from `main`, which is not ideal but acceptable since no release
has been cut. Reverting now buys time to discuss without breaking
customers later.

## Removed

- `ServiceUrlValidator` class and `ServiceUrlValidatorTests`
- `AppOptions.AdditionalAllowedDomains`, `App._additionalAllowedDomains`
field, related warn log, and the `IsAllowed` check in `App.Process`
- `TeamsSettings.AdditionalAllowedDomains` and its `Apply()` assignment
- `CloudEnvironment.AllowedServiceUrls` property, per-cloud entries
(Public/USGov/USGovDoD/China), constructor parameter, and
`WithOverrides` parameter

## Preserved (other security work bundled into PR #418)

- DevTools production guard (`DevToolsPlugin`,
`TeamsValidationSettings`)

## Preserved (sovereign cloud, separate work)

`CloudEnvironment` presets, `WithOverrides`, `FromName`,
`AppOptions.Cloud`, and the per-cloud `Bots.Token.ActiveBotScope` /
`ActiveGraphScope` / `TokenServiceUrl` wiring in `App` are unchanged.

## Note on related open PRs

PR #450 (`Tighten AdditionalAllowedDomains API contract`) and PR #413
(sovereign cloud next/core, which carries this plumbing) are
intentionally left open for separate decisions.

## Test plan

- [x] `dotnet build` clean (0 errors, 5 unrelated pre-existing warnings)
- [x] `dotnet test` net10.0 passes (net8.0 testhost aborted on local
machine due to missing SDK, environmental, not code)
- [x] Smoke test: `Samples/Samples.Echo` starts and binds to port
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