Add sovereign cloud support (GCCH, DoD, China)#500
Conversation
837bcd3 to
3a57872
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds first-class sovereign cloud support by introducing a CloudEnvironment abstraction (public, US Gov, DoD, China) and threading it through token acquisition, API client configuration, and JWT validation so endpoints/issuers/JWKS can vary by cloud.
Changes:
- Added
CloudEnvironmentpresets plus helpers (fromName,withOverrides) and exported them from the auth package. - Threaded
cloudthroughApp,TokenManager, API client settings, and JWT validators (including support forCLOUDenv var). - Updated service token validation to use cloud-specific issuer and JWKS metadata-derived keys endpoint, with accompanying tests.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/api/src/auth/cloud-environment.ts | Defines cloud presets + name/override helpers for sovereign endpoints. |
| packages/api/src/auth/cloud-environment.spec.ts | Adds tests covering presets, fromName, and withOverrides. |
| packages/api/src/auth/index.ts | Re-exports cloud-environment from the auth barrel. |
| packages/api/src/clients/api-client-settings.ts | Allows default OAuth/token service URL to come from CloudEnvironment. |
| packages/api/src/clients/index.ts | Threads optional cloud into client settings merging. |
| packages/apps/src/app.ts | Resolves cloud from options or CLOUD env var and passes it through to API/auth components. |
| packages/apps/src/token-manager.ts | Uses cloud bot scope/authority endpoints for token acquisition. |
| packages/apps/src/middleware/auth/jwt-validator.ts | Adds loginEndpoint support for JWKS URI construction and issuer prefix validation. |
| packages/apps/src/middleware/auth/service-token-validator.ts | Uses cloud issuer + OpenID metadata-derived JWKS keys URI. |
| packages/apps/src/middleware/auth/service-token-validator.spec.ts | Adds sovereign cloud test coverage for issuer/JWKS URI selection. |
| packages/apps/src/middleware/jwt-validation-middleware.ts | Accepts cloud param and passes it into service token validation. |
| packages/apps/src/http/http-server.ts | Passes cloud into ServiceTokenValidator during server initialization. |
Comments suppressed due to low confidence (1)
packages/apps/src/token-manager.ts:75
getGraphToken()still uses the public cloud scope (https://graph.microsoft.com/.default) even when the token authority is switched viacloud.loginEndpoint. In sovereign clouds, Graph typically has different resource/scope values (e.g.https://graph.microsoft.us/.default), so token acquisition can fail or produce a token for the wrong audience. Consider adding a Graph scope/base URL toCloudEnvironmentand using it here instead of the hard-coded constant.
async getGraphToken(tenantId?: string): Promise<IToken | null> {
return await this.getToken(DEFAULT_GRAPH_TOKEN_SCOPE, this.resolveTenantId(tenantId, DEFAULT_TENANT_FOR_GRAPH_TOKEN));
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
3a57872 to
3e3064e
Compare
Review note: Graph token scope needs to vary per cloudGreat work on sovereign cloud support! One gap I noticed: const DEFAULT_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 Correct Graph scopes per cloud
Note: DoD uses Reference: Microsoft Graph national cloud deployments Suggested fix
Small change — one new field on the type, one line update in |
Introduce CloudEnvironment type with predefined presets (PUBLIC, US_GOV, US_GOV_DOD, CHINA) bundling all cloud-specific service endpoints. Thread cloud environment through App, TokenManager, ApiClient, JwtValidator, and ServiceTokenValidator so previously hardcoded endpoints are configurable per cloud. Supports programmatic configuration via AppOptions.cloud or CLOUD environment variable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- CloudEnvironment: preset values, fromName(), withOverrides(), frozen checks - ServiceTokenValidator: verify cloud-specific issuer and JWKS URI for US_GOV/CHINA - JwtValidator: loginEndpoint for JWKS URI construction and issuer prefix validation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8f9d0b2 to
634f391
Compare
Summary
CloudEnvironmenttype with predefined presets (PUBLIC,US_GOV,US_GOV_DOD,CHINA) bundling all cloud-specific service endpointsApp,TokenManager,ApiClient,JwtValidator, andServiceTokenValidatorCLOUDenvironment variable and programmaticAppOptions.cloudconfigurationgraphScopetoCloudEnvironmentfor cloud-aware Microsoft Graph token acquisitionNote
graphBaseUrl(Graph API endpoint per cloud) is intentionally deferred. This PR focuses on auth/token acquisition. Graph API routing is a separate concern and the Graph client already accepts abaseUrlRootoverride.Sources
Test plan
npm run build-- 34/34 tasks passnpm test-- 591 tests passCLOUD=USGovagainst real GCCH tenant -- JWT validated, echo reply sent🤖 Generated with Claude Code