azure-sdk-for-js: [Identity] Token mixed when using the same DefaultAzureCredential instance for different service clients (e.g. AppConfig and KeyVault), resulting in errors.

  • Package Name: @azure/identity
  • Package Version: 3.2.2
  • Operating system: Windows
  • nodejs
    • version: 18.15.0
  • browser
    • name/version:
  • typescript
    • version:
  • Is the bug related to documentation in

Describe the bug If we use only one instance of DefaultAzureCredential for different services like App Configuration and Key Vault, the token used to call the services seems mixed and leads to error. The following error is a custom one when we try to load a key from key vault (check “how to reproduce” part for more information) :

Failed to get AKeyVerySecretForTicket from Key Vault: [401] AKV10022: Invalid audience. Expected https://vault.azure.net, found: https://name-of-app-config-very-secret.azconfig.io., will retry in 300000

To Reproduce

const { DefaultAzureCredential } = require('@azure/identity');
const { SecretClient } = require('@azure/keyvault-secrets');
const { AppConfigurationClient } = require('@azure/app-configuration');

const credential = new DefaultAzureCredential();

const keyVaultName = process.env.KEYVAULT_NAME;
const appConfigName = process.env.APPCONFIG_NAME;

const keyVaultClient = new SecretClient(`https://${keyVaultName}.vault.azure.net`, credential);
const appConfigClient = new AppConfigurationClient(`https://${appConfigName}.azconfig.io`, credential);
setImmediate(async () => {
     const res = await Promise.all([
        getAppConfigValue("AnotherKeyVerySecretForTicket"),
        getKeyVaultValue("AKeyVerySecretForTicket")
    ]);
    
    // Do something really important with the values
    console.log(res);
});

async function getAppConfigValue(key) {
    try {
        const result = await appConfigClient.getConfigurationSetting({ key });
        return result.value;
    } catch (error) {
        console.error(`Failed to get ${key} from App Config: [${error.statusCode}] ${error.message}, will retry.`);
        throw error;
    }
}
async function getKeyVaultValue(key) {
    try {
        const result = await keyVaultClient.getSecret(key);
        return result.value;
    } catch (error) {
        console.error(`Failed to get ${key} from Key Vault: [${error.statusCode}] ${error.message}, will retry.`);
        throw error;
    }
}

Expected behavior No error and the token fetched for App Configuration should not be used for calling Key Vault since the audience isn’t the same

More context Trying to understand this obscure behavior (since it was working before the upgrade to 3.2.x where we were using version 3.1.4), we tried to stringify the DefaultAzureCredential instance and we saw that the token in the cache was the same for both AppConfig and KeyVault services… Also, we can’t reproduce this bug in local environment. The bug seems to occur when we host the code in App Service and the DefaultAzureCredential use managed Identity

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 1
  • Comments: 16 (6 by maintainers)

Commits related to this issue

Most upvoted comments

Folks, I have figured what the issue is. This is a bug related to parameters being passed to an internal function for token caching. Working on the fix for this. Meanwhile, please use the workaround of instantiating separate credentials for MI for the consecutive clients. Thanks!