Azure-sdk-for-net: [BUG] Azure.Identity - SharedTokenCacheCredential AKV10032 - Key Vault in different tenant than credential home tenant

Created on 24 Apr 2020  ·  4Comments  ·  Source: Azure/azure-sdk-for-net

Describe the bug
Connecting to get Key Vault Secret from tenant that is different from the home tenant of my credential for localhost development (using Visual Studio cached credential store via "Azure Service Authentication") throws 401 response with AKV10032: Invalid issuer.

Expected behavior
Vault should be able to connect (portal, CLI, AZ PS, and OLD nuget Microsoft.Azure.Keyvault all working)
Ex: this works from Microsoft.Azure.Keyvault

AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider("RunAs=Developer; DeveloperTool=VisualStudio"); 
var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));

*Actual behavior *

Something went wrong: Service request failed.
Status: 401 (Unauthorized)

Content:
{"error":{"code":"Unauthorized","message":"AKV10032: Invalid issuer. Expected one of https://sts.windows.net/{GUID of tenant where keyvault lives}/, https://sts.windows.net/f8cdef31-a31e-4b4a-93e4-5f571e91255a/, https://sts.windows.net/e2d54eb5-3869-4f70-8578-dee5fc7331f4/, found https://sts.windows.net/{GUID of my home tenant's Azure Sub}/."}}

To Reproduce
Steps to reproduce the behavior

  1. Add a B2B GUEST account into AAD where keyvault lives, grant it access
  2. Sign into Visual Studio with B2B Guest account - ensure it is in the ONLY cred in "Azure Service Authentication" list.
  3. Use new Azure.Security.KeyVault to connect to vault.

Tried to specify either and both the TenantId and UserName properties - neither work:

DefaultAzureCredentialOptions() { SharedTokenCacheTenantId = "{GUID of tenant where keyvault lives}", SharedTokenCacheUsername = "{Guest user}" };

and
SharedTokenCacheCredentialOptions localCredsOptions = new SharedTokenCacheCredentialOptions();
localCredsOptions.TenantId = "{GUID of tenant where keyvault lives}";
localCredsOptions.Username = "{Guest user}";

IF i specify both:

Something went wrong: SharedTokenCacheCredential authentication unavailable. No account matching the specified username: {specified user} tenantId: {specified tenant} was found in the cache.

IF i specify only Tenant:

Something went wrong: SharedTokenCacheCredential authentication unavailable. No account matching the specified tenantId: {specified tenant} was found in the cache.

IF i specify only UserName

401 - AKV10032

Environment:

  • Azure.Identity 1.1.1 / 1.2.0-preview2 and Azure.Security.KeyVault.Secrets 4.0.3 / 4.1.0-preview.1
  • Windows 10 - .NET 4.7 4.0.30319.42000
  • IDE and version :Visual Studio 2019 / Linqpad 5.4.1
Azure.Identity Client customer-reported question

Most helpful comment

@felickz thanks for the additional information. Another possibility is to disable the SharedTokenCacheCredential entirely

~ c#
DefaultAzureCredentialOptions options = new DefaultAzureCredentialOptions() { ExcludeSharedTokenCacheCredential = true, VisualStudioTenantId = "{GUID of tenant where keyvault lives}" };
~

Also, we're most likely adding a TenantId property to DefaultAzureCredentialOptions which would prevent you from having to multiple properties to effectively authenticate to a specific tenant. We welcome any thoughts you have on this.

I'm going to close this issue since I believe it's been addressed even though we do have other improvements still to come. If you disagree please feel free to re-open the issue, Thanks again for your feedback!

All 4 comments

Also, assuming this is unsupported at the moment - as there is no documentation for SharedTokenCacheCredential on docs?

@felickz Thanks for reporting this issue. Currently this is a known issue we're tracking in https://github.com/Azure/azure-sdk-for-net/issues/8957. Unfortunately this is a current limitation of the SharedTokenCacheCredential. However, in Azure.Identity 1.2.0-preview we added the VisualStudioCredential to the DefaultAzureCredential authentication flow, which I believe will unblock this scenario of signing into a guest tenant when authenticating via VS. If you log into VS with the desired account, and then specify the tenant you wish to authenticate in either via the AZURE_TENANT_ID environment variable or the VisualStudioTenantId property on DefaultAzureCredentialOptions this will authenticate the account to the desired tenant.

Please let me know if this works for you or if you still are having issues authenticating to the appropriate tenant via Visual Studio.

@schaabs thanks for looking into my ticket, i had upgraded to preview nuget but did not take notice of any new properties until you mentioned it...

Indeed VisualStudioTenantId = "{GUID of tenant where keyvault lives}" this did resolve the issue as long as i _also_ specified SharedTokenCacheTenantId = "{GUID of tenant where keyvault lives}":

DefaultAzureCredentialOptions options = new DefaultAzureCredentialOptions() { VisualStudioTenantId = "{GUID of tenant where keyvault lives}", SharedTokenCacheTenantId = "{GUID of tenant where keyvault lives}" };

NOTE: if i specify VisualStudioTenantId but exclude SharedTokenCacheTenantId from the config - then i get the same initial error:

Something went wrong: Service request failed.
Status: 401 (Unauthorized)

Content:
{"error":{"code":"Unauthorized","message":"AKV10032: Invalid issuer. Expected one of https://sts.windows.net/{GUID of tenant where keyvault lives}/, https://sts.windows.net/f8cdef31-a31e-4b4a-93e4-5f571e91255a/, https://sts.windows.net/e2d54eb5-3869-4f70-8578-dee5fc7331f4/, found https://sts.windows.net/{GUID of my home tenant's Azure Sub}/."}}

Headers:
Pragma: no-cache
x-ms-keyvault-region: eastus2
x-ms-request-id: REDACTED
x-ms-keyvault-service-version: 1.1.0.898
x-ms-keyvault-network-info: addr=REDACTED;act_addr_fam=InterNetwork;
Strict-Transport-Security: REDACTED
X-Content-Type-Options: REDACTED
Cache-Control: no-cache
Date: Mon, 27 Apr 2020 21:01:38 GMT
Server: Microsoft-IIS/10.0
WWW-Authenticate: REDACTED
X-AspNet-Version: REDACTED
X-Powered-By: REDACTED
Content-Length: 345
Content-Type: application/json; charset=utf-8
Expires: -1

@felickz thanks for the additional information. Another possibility is to disable the SharedTokenCacheCredential entirely

~ c#
DefaultAzureCredentialOptions options = new DefaultAzureCredentialOptions() { ExcludeSharedTokenCacheCredential = true, VisualStudioTenantId = "{GUID of tenant where keyvault lives}" };
~

Also, we're most likely adding a TenantId property to DefaultAzureCredentialOptions which would prevent you from having to multiple properties to effectively authenticate to a specific tenant. We welcome any thoughts you have on this.

I'm going to close this issue since I believe it's been addressed even though we do have other improvements still to come. If you disagree please feel free to re-open the issue, Thanks again for your feedback!

Was this page helpful?
0 / 5 - 0 ratings