How to use Azure.Identity with Azure Government Cloud, Azure German Cloud, and Azure China Cloud

Azure has many cloud instances like: Azure Public, Azure Government, Azure German, and Azure China. You can see the full cloud list and associated endpoints via the Azure CLI command az cloud list.

If you try to use the new Azure Identity SDK with one of those clouds, you will get this error:

AADSTS900382: Confidential Client is not supported in Cross Cloud request

That is because all of the SDKs default to using https://login.microsoftonline.com as the Azure Active Diretory authority host. Each of the other clouds have different authority host endpoints, as you can see from the Azure Government profile here:

The activeDirectory property doesn’t end with .com it ends with .us, and every cloud is different.

{
    "endpoints": {
      "activeDirectory": "https://login.microsoftonline.us",
      "activeDirectoryDataLakeResourceId": null,
      "activeDirectoryGraphResourceId": "https://graph.windows.net/",
      "activeDirectoryResourceId": "https://management.core.usgovcloudapi.net/",
      "batchResourceId": "https://batch.core.usgovcloudapi.net/",
      "gallery": "https://gallery.usgovcloudapi.net/",
      "management": "https://management.core.usgovcloudapi.net/",
      "mediaResourceId": "https://rest.media.usgovcloudapi.net",
      "microsoftGraphResourceId": "https://graph.microsoft.us/",
      "ossrdbmsResourceId": "https://ossrdbms-aad.database.usgovcloudapi.net",
      "resourceManager": "https://management.usgovcloudapi.net/",
      "sqlManagement": "https://management.core.usgovcloudapi.net:8443/",
      "vmImageAliasDoc": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/arm-compute/quickstart-templates/aliases.json"
    },
    "isActive": true,
    "name": "AzureUSGovernment",
    "profile": "latest",
    "suffixes": {
      "acrLoginServerEndpoint": ".azurecr.us",
      "azureDatalakeAnalyticsCatalogAndJobEndpoint": null,
      "azureDatalakeStoreFileSystemEndpoint": null,
      "keyvaultDns": ".vault.usgovcloudapi.net",
      "sqlServerHostname": ".database.usgovcloudapi.net",
      "storageEndpoint": "core.usgovcloudapi.net"
    }
  },

When you instantiate Azure.Identity.DefaultAzureCredential() without any parameters:

const credential = new DefaultAzureCredential();

You will get the following error:

AADSTS900382: Confidential Client is not supported in Cross Cloud request

What you need to do is instantiate DefaultAzureCredential with the proper authority host for the cloud you are targeting. Run az cloud list to find the appropriate activeDirectory endpoint.

Here’s what you need to do for each language:

You will notice that some languages allow you to use a KnownAuthority enum while others require that you enter the full URL. I have filed issues with each of the other languages to support KnownAuthorities as well: https://github.com/Azure/azure-sdk/issues/1054

.NET

// Version 1.2.0-preview.1 or greater
var options = new DefaultAzureCredentialOptions { AuthorityHost = KnownAuthorityHosts.AzureUSGovernment };

// Versions prior to 1.2.0-preview.1
// var options = new DefaultAzureCredentialOptions { AuthorityHost =  new Uri("https://login.microsoftonline.us/") };
var client = new KeyClient(new Uri(keyVaultUrl), new DefaultAzureCredential(options));

Java

Option 1 (Version 1.1.0-beta.2 +)

NOTE: The DefaultAzureCredentialBuilder().authorityHost method was introduced in azure-identityversion 1.1.0-beta.2. Please include the following in your pom.xml file

pom.xml

<dependencies>
  <dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-identity</artifactId>
    <version>1.1.0-beta.2</version>
  </dependency>
</dependencies>

App.java


// Version 1.1.0-beta.2 or greater
DefaultAzureCredential cred = new DefaultAzureCredentialBuilder()
  .authorityHost("https://login.microsoftonline.us/").build();

KeyClient keyClient = new KeyClientBuilder().vaultUrl(dotenv.get("AZURE_KEYVAULT_URL")).credential(cred)
  .buildClient();

Prior to version 1.1.0-beta.2 it was not possible to set the DefefaultAzureCredential.authorityHost. You have two options if you cannot use v1.1.0-beta.2

Option 2

Only needed if you can’t use 1.1.0-beta.2+

Use reflection to set the underlying identityClientOptions property:

IdentityClientOptions options = new IdentityClientOptions().setAuthorityHost("https://login.microsoftonline.us/");
DefaultAzureCredentialBuilder cred = new DefaultAzureCredentialBuilder();
Field identityClientOptions = cred.getClass().getSuperclass().getDeclaredField("identityClientOptions");
identityClientOptions.setAccessible(true);
identityClientOptions.set(cred, options);

KeyClient keyClient = new KeyClientBuilder().vaultUrl(dotenv.get("AZURE_KEYVAULT_URL"))
  .credential(cred.build()).buildClient();

Option 3

Only needed if you can’t use reflection and can’t use 1.1.0-beta.2+

Use the EnvironmentCredentialBuilder class instead of DefaultAzureCredentialBuilder:

KeyClient keyClient = new KeyClientBuilder().vaultUrl(dotenv.get("AZURE_KEYVAULT_URL"))
  .credential(new EnvironmentCredentialBuilder().authorityHost("https://login.microsoftonline.us/").build()).buildClient();

Python

credential = DefaultAzureCredential(authority=KnownAuthorities.AZURE_GOVERNMENT)

TypeScript

const credential = new DefaultAzureCredential({ authorityHost: "https://login.microsoftonline.us" });