Skip to content

Add sovereign cloud support (GCCH, DoD, China)#354

Open
corinagum wants to merge 8 commits intomainfrom
cg/sovereign-cloud
Open

Add sovereign cloud support (GCCH, DoD, China)#354
corinagum wants to merge 8 commits intomainfrom
cg/sovereign-cloud

Conversation

@corinagum
Copy link
Copy Markdown
Contributor

@corinagum corinagum commented Apr 3, 2026

Summary

  • Introduces CloudEnvironment frozen dataclass with predefined presets (PUBLIC, US_GOV, US_GOV_DOD, CHINA) bundling all cloud-specific service endpoints
  • Threads cloud environment through App, TokenManager, BotTokenClient, TokenValidator, ApiClient, and ApiClientSettings
  • Supports CLOUD environment variable and programmatic AppOptions.cloud configuration
  • Adds graph_scope to CloudEnvironment for cloud-aware Microsoft Graph token acquisition
  • Simplifies merge_api_client_settings with cloud default to PUBLIC, removes DEFAULT_API_CLIENT_SETTINGS
  • Fixes cloud propagation through ApiClient -> BotClient -> BotTokenClient

Note

graph_base_url (Graph API endpoint per cloud) is intentionally deferred. This PR focuses on auth/token acquisition. Graph API routing is a separate concern.

Sources

Test plan

  • pytest packages/api/tests/ -- 168 tests pass
  • pytest packages/apps/tests/ -- 389 tests pass (1 pre-existing failure unrelated)
  • E2E: Echo bot with CLOUD=USGov against real GCCH tenant -- message received, echo reply sent
  • Copilot review feedback addressed

🤖 Generated with Claude Code

@corinagum corinagum force-pushed the cg/sovereign-cloud branch from 3f52061 to a0cb16d Compare April 7, 2026 21:12
@corinagum corinagum marked this pull request as ready for review April 7, 2026 21:12
Copilot AI review requested due to automatic review settings April 7, 2026 21:12
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

Adds a first-class cloud environment abstraction to support sovereign clouds (GCCH, DoD, China) by centralizing cloud-specific endpoints and plumbing a CloudEnvironment option through key authentication/token-validation paths.

Changes:

  • Introduces CloudEnvironment (frozen dataclass) with presets (PUBLIC, US_GOV, US_GOV_DOD, CHINA) plus helpers (from_name, with_overrides).
  • Threads cloud configuration into apps auth/token flows (App, TokenManager, TokenValidator, HttpServer, JWT middleware), including CLOUD env var resolution.
  • Updates API client pieces to accept cloud-aware defaults and adds unit coverage for cloud presets/helpers.

Reviewed changes

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

Show a summary per file
File Description
packages/api/src/microsoft_teams/api/auth/cloud_environment.py New cloud endpoint bundle + presets + name/override helpers.
packages/api/tests/unit/test_cloud_environment.py Unit tests for presets, name resolution, overrides, immutability.
packages/api/src/microsoft_teams/api/auth/init.py Exposes CloudEnvironment and presets/helpers from the auth package.
packages/api/src/microsoft_teams/api/clients/api_client_settings.py Adds cloud-aware defaulting behavior for token service (oauth_url).
packages/api/src/microsoft_teams/api/clients/init.py Adjusts exports for client settings helpers.
packages/api/src/microsoft_teams/api/clients/bot/token_client.py Adds optional cloud parameter and uses cloud endpoints/scope.
packages/apps/src/microsoft_teams/apps/options.py Adds cloud option typing for app configuration.
packages/apps/src/microsoft_teams/apps/app.py Resolves cloud from options/CLOUD env var and passes into auth components.
packages/apps/src/microsoft_teams/apps/token_manager.py Uses cloud-specific authority, scope, and default tenant for bot tokens.
packages/apps/src/microsoft_teams/apps/auth/token_validator.py Makes JWKS/issuer/login endpoints cloud-aware for service + Entra validation.
packages/apps/src/microsoft_teams/apps/auth/jwt_middleware.py Adds cloud option and passes it through to service token validator.
packages/apps/src/microsoft_teams/apps/http/http_server.py Passes cloud into service token validator for request auth.

Copy link
Copy Markdown
Collaborator

@heyitsaamir heyitsaamir left a comment

Choose a reason for hiding this comment

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

Hm, it looks like cloud simply overrides a number of application-level settings. Can we localize its spread to just app, and maybe the token-validator?? Basically if CLOUD is set, then we set many of those values up and log it?

@corinagum corinagum force-pushed the cg/sovereign-cloud branch from e8688ad to c8ddc09 Compare April 8, 2026 23:30
@rajan-chari
Copy link
Copy Markdown
Contributor

Review note: Graph token scope needs to vary per cloud

Great work on sovereign cloud support! One gap I noticed: get_graph_token() in token_manager.py still hardcodes the public cloud Graph scope:

GRAPH_TOKEN_SCOPE = 'https://graph.microsoft.com/.default'

This will fail for sovereign clouds — the Graph API endpoint domain differs per cloud, and using the wrong audience returns AADSTS500011 or AADSTS650001.

Correct Graph scopes per cloud

Cloud Graph Scope
Public https://graph.microsoft.com/.default
US Gov (GCC High) https://graph.microsoft.us/.default
US Gov (DoD) https://dod-graph.microsoft.us/.default
China (21Vianet) https://microsoftgraph.chinacloudapi.cn/.default

Note: DoD uses dod-graph.microsoft.us, not graph.microsoft.us — the two US Gov presets need different graph scopes.

Reference: Microsoft Graph national cloud deployments

Suggested fix

  1. Add a graph_scope field to CloudEnvironment
  2. Set it correctly in all 4 cloud presets
  3. TokenManager.get_graph_token() reads cloud.graph_scope instead of the hardcoded constant

Small change — one new field on the dataclass, one line update in token_manager.py.

@corinagum corinagum force-pushed the cg/sovereign-cloud branch from c8ddc09 to 3da56ca Compare April 9, 2026 18:44
Corina Gum and others added 6 commits April 10, 2026 09:30
Introduce CloudEnvironment frozen dataclass with predefined presets
(PUBLIC, US_GOV, US_GOV_DOD, CHINA) bundling all cloud-specific service
endpoints. Thread cloud environment through App, TokenManager,
BotTokenClient, TokenValidator, and ApiClientSettings so previously
hardcoded endpoints are configurable per cloud.

Supports programmatic configuration via AppOptions cloud parameter or
CLOUD environment variable.

Includes comprehensive tests for CloudEnvironment presets, from_name(),
and with_overrides().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Thread cloud param through ApiClient -> BotClient -> BotTokenClient so
direct token acquisition via api.bots.token uses sovereign cloud endpoints.
Add unit tests verifying cloud propagation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@corinagum corinagum force-pushed the cg/sovereign-cloud branch from 9e5091b to 25b19ce Compare April 10, 2026 16:31
Copy link
Copy Markdown
Collaborator

@heyitsaamir heyitsaamir left a comment

Choose a reason for hiding this comment

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

Looks good. Some minor nits. Also, looks like not all the fields are actually used. Is that intentional?

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.

6 participants