If your product reads mail or calendars through Microsoft Graph, a customer in GCC High or DoD is not one configuration flag away. Their tenant lives in a separate instance of Microsoft’s cloud, with its own sign-in service, its own Graph host and its own app registrations. This article lists what actually changes, from Microsoft’s documentation and from what workwae’s provider code does for each cloud.
Four clouds, and where GCC fits.
Microsoft describes its national clouds as physically and logically network-isolated instances of its enterprise services (Microsoft Graph national cloud deployments). For mail and calendars there are four environments to plan for:
- Worldwide, including GCC: sign-in at
login.microsoftonline.com, Graph atgraph.microsoft.com. - GCC High: sign-in at
login.microsoftonline.us, Graph atgraph.microsoft.us. - DoD: sign-in at
login.microsoftonline.us, Graph atdod-graph.microsoft.us. - 21Vianet (China): sign-in at
login.chinacloudapi.cn, Graph atmicrosoftgraph.chinacloudapi.cn.
GCC (moderate) is the one that surprises people: Microsoft tells GCC developers to keep using the worldwide endpoints, so a GCC tenant behaves like a commercial one. GCC High and DoD share a sign-in host but not a Graph host. Personal Microsoft accounts exist only in the worldwide cloud.
Exchange Online has its own hosts as well. IMAP is outlook.office365.us in GCC
High and outlook-dod.office365.us in DoD
(GCC High endpoints,
DoD endpoints).
Both clouds receive mail through protection.office365.us, so an MX lookup tells
you a domain is in a US government cloud but not which one. Ask the customer.
One app registration per cloud.
Microsoft’s identity documentation is explicit: to use the identity platform in a
national cloud, you are required to register your application separately in that
cloud’s portal (National clouds).
For US government that is portal.azure.us. An app registered in the worldwide
portal does not exist in GCC High, and its client id means nothing to
login.microsoftonline.us.
Tokens follow the same line. Access tokens acquired for one national cloud are not interchangeable with those of the global service or any other cloud. Three consequences for your code:
- Scopes name the cloud’s Graph root. workwae asks a GCC High user
for
https://graph.microsoft.us/Mail.ReadWrite, withMail.SendandUser.Readunder the same prefix, and adds calendar and contacts scopes only when those features are on. - The issuer changes. An ID token from GCC High or DoD is issued by
https://login.microsoftonline.us/{tenant}/v2.0, so issuer checks written for the worldwide host reject it. - Stored grants need a cloud. A refresh token refreshes only against the cloud and app that issued it, so the cloud has to be stored with every account and every app.
With workwae, you register your Entra app once per cloud and say which cloud it belongs to. Users then sign in from your own interface:
const app = await workwae.oauthApps.create({
provider: "microsoft",
cloud: "gcc-high",
name: "Example Mail",
clientId: process.env.ENTRA_CLIENT_ID!,
clientSecret: process.env.ENTRA_CLIENT_SECRET!,
authority: process.env.ENTRA_DIRECTORY_ID!,
});
const { authorizeUrl } = await workwae.oauthAuthorizations.create({
provider: "microsoft",
oauthAppId: app.id,
redirectUri: "https://app.example.com/mail/connected",
externalRef: user.id,
state: csrfToken,
options: { calendarEnabled: true },
});
The account takes the app’s cloud, and every call for it goes to that cloud’s
hosts. A refresh token your GCC High app already holds connects the same way, through
accounts.create with the app’s id
(Connect flows).
Admin consent and app-only access.
Many government tenants block user consent, so an administrator approves the app for the
whole directory. The admin consent endpoint has the same shape in every cloud,
/{tenant}/v2.0/adminconsent on the cloud’s sign-in host
(Admin consent protocols), but
the scope it grants is the cloud’s own: https://dod-graph.microsoft.us/.default
for a DoD app. Application tokens then come from the same host through the client
credentials grant, for the same .default scope.
workwae calls these organization connections. You register the app with its cloud, send an administrator to the consent URL, and test the connection before adding mailboxes (Organization connections):
const connection = await workwae.orgConnections.create({
kind: "microsoft_app",
name: "Contoso (DoD)",
cloud: "dod",
credential: { type: "client_secret", clientId, clientSecret },
});
// Send the administrator here
const { consentUrl } = await workwae.orgConnections.consent({
connectionId: connection.id,
redirectUri: "https://app.example.com/admin/consent-done",
state: tenantRef,
});
// After consent: request a token the way accounts will
const { checks } = await workwae.orgConnections.test({ connectionId: connection.id }); The test reports each check, so a missing permission shows up before a mailbox does. Certificate credentials work as well as client secrets.
What behaves differently.
Most of Graph’s mail and calendar surface is the same in GCC High and DoD. Each Graph API reference page lists the national clouds it is available in, and a few rows matter for an email integration:
- Permanent delete.
permanentDeleteon a message is available only in the global service (message: permanentDelete). In GCC High and DoD, workwae falls back toDELETE, which moves the message to Recoverable Items instead of purging it. - Message delta.
message: deltais available in GCC High and DoD but not in 21Vianet (message: delta). That is why workwae syncs 21Vianet mail over IMAP and SMTP with Microsoft sign-in, and GCC High and DoD mail over Graph. - Change notifications. Where a cloud lacks them, workwae’s scheduled poll keeps the account current.
- Teams meetings. Graph reports which online meeting providers each
calendar allows. workwae adds a Teams meeting to an event only when the calendar lists
teamsForBusiness, and otherwise refuses the request rather than create an event without a link. - Tooling. Graph Explorer is not supported in GCC High or DoD, so test calls go through your own app registration.
How workwae handles it.
-
Every Microsoft account and OAuth app records its cloud:
global,gcc-high,dodorchina. GCC tenants useglobal. - Sign-in, token refresh, Graph, IMAP and SMTP for an account all use its cloud’s hosts, and tokens never cross clouds.
-
You bring your own app registration per cloud, or use workwae’s where we run one
by passing
microsoftCloudto a hosted connect session or a headless authorization. A cloud without a workwae app answersprovider_not_configured. -
Government and commercial accounts share one workspace and one SDK, and
account.connectedtells your backend which cloud each account is in.
// Your webhook, when the account is ready (abridged)
{
"type": "account.connected",
"data": {
"email": "ada@agency.example",
"provider": "graph",
"cloud": "dod",
"externalRef": "user-42",
"reauthorized": false
}
} The government use case summarizes the same setup, and the quickstart goes from API key to first sent message.
Limits.
Check these against your contract and your customers’ requirements before you build:
- No FedRAMP authorization. workwae holds no FedRAMP or other government authorization, and claims no certification.
- Not in a government cloud region. Data is stored and processed on AWS in the United States, not in a government region (Subprocessors).
- Commercial Zoom and Webex only. Meetings are created through the commercial Zoom and Webex services; their government services are not supported.
- SOC 2 planned, not started. The audit has not begun.
- Hosted only. There is no self-hosted or on-premises option.
If those fit, the per-cloud work above is what workwae takes off your hands. How workwae compares shows which other email APIs document national cloud support.