How to Connect to Azure GCC High Tenants Using C# and Microsoft Graph SDK
Integrating applications with Microsoft 365 government environments like Azure GCC High or Azure Government requires specific endpoints, authority hosts, and correct authentication flows. When using the modern Microsoft Graph .NET SDK (v5+), developers often run into confusing errors such as Invalid version or authentication failures.
The Core Issues Explained
If you encounter an Invalid version error when executing a Graph request in an Azure Government tenant, the issue typically stems from two main causes:
1. Missing API Version in the Graph Service Root
In Microsoft Graph .NET SDK (v5 and v6), the SDK constructs URL paths by appending endpoint segments to the base service URL. If you provide https://graph.microsoft.us/ without the API version, the generated request URL becomes invalid (e.g., https://graph.microsoft.us/me instead of https://graph.microsoft.us/v1.0/me). The base endpoint for US Government must include the API version:
// Correct base URL for Graph v1.0 in US Gov / GCC High
string graphServiceRoot = "https://graph.microsoft.us/v1.0";2. Using /me with Client Secret Credentials (App-Only Flow)
The ClientSecretCredential authenticates as an application (Service Principal), not as an interactive user. The /me endpoint only works when a delegated user token is present. When using application permissions (Client Credentials), you must specify a target user via the Users["user@domain.onmicrosoft.us"] collection to access mailboxes or calendars.
Complete Working Example
Here is a complete, updated example targeting .NET 8 (or .NET Framework 4.8) using the latest Microsoft.Graph and Azure.Identity libraries:
using System;
using System.Threading.Tasks;
using Azure.Identity;
using Microsoft.Graph;
class Program
{
static async Task Main(string[] args)
{
string tenantId = "your-gcc-high-tenant-id";
string clientId = "your-client-app-id";
string clientSecret = "your-client-secret";
string targetUserUpn = "user@yourdomain.onmicrosoft.us"; // Target GCC High mailbox
// 1. Configure the Sovereign Cloud Authority Host
var credentialOptions = new ClientSecretCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzureGovernment // https://login.microsoftonline.us
};
var credential = new ClientSecretCredential(
tenantId,
clientId,
clientSecret,
credentialOptions
);
// 2. Define the US Gov Scopes and Service Root (with /v1.0)
string[] scopes = new[] { "https://graph.microsoft.us/.default" };
string baseUrl = "https://graph.microsoft.us/v1.0";
// 3. Initialize GraphServiceClient with Government Base URL
var graphClient = new GraphServiceClient(credential, scopes, baseUrl);
try
{
// 4. Query the user's calendar events (avoid /me for app-only tokens)
var events = await graphClient.Users[targetUserUpn].Calendar.Events.GetAsync(requestConfig =>
{
requestConfig.QueryParameters.Top = 10;
requestConfig.QueryParameters.Select = new[] { "subject", "start", "end" };
});
if (events?.Value != null)
{
foreach (var evt in events.Value)
{
Console.WriteLine($"Event: {evt.Subject} ({evt.Start?.DateTime} - {evt.End?.DateTime})");
}
}
}
catch (ServiceException ex)
{
Console.WriteLine($"Graph API Error: {ex.Message}");
}
}
}Key Takeaways for Azure Government / GCC High
- Authority Host: Always specify
AzureAuthorityHosts.AzureGovernmentin yourAzure.Identitycredential options. - Scope URL: Ensure scopes use the US Gov endpoint:
https://graph.microsoft.us/.default. - Base URL: Explicitly append
/v1.0or/betatohttps://graph.microsoft.uswhen initializingGraphServiceClient. - App-Only Access: Ensure your App Registration in the Azure Government portal has
Calendars.ReadorCalendars.ReadWriteApplication permissions granted with Admin Consent.