Azure.Identity: support MSI_CLIENT_ID or AZURE_CLIENT_ID env var for User Assigned Identities
See original GitHub issueLibrary or service name. Azure.Identity.
Is your feature request related to a problem? Please describe.
This affects App Services and Function Apps with user assigned identity.
The standard method to obtain credential in app service is this:
credentials = new DefaultAzureCredential();
As per docs, this will try to obtain token using this chain: Environment, Managed Identity, Visual Studio, VS Code, Azure CLI.
All good and well, except that does not work with User Assigned Managed Identities, it only works with System Assigned MSIs.
The reason for this is we need to specify client id of User Assigned MSI.
This leads to many undesirable things:
- Separate code paths just for User Assigned MSI.
- Figuring out if we run locally on in Azure to support local machine scenarios. E.g. this is the kind of code we need to write:
TokenCredential credentials;
var _isLocal = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME"));
if (_isLocal)
{
Console.WriteLine("Using local DefaultAzureCredential");
credentials = new DefaultAzureCredential();
}
else
{
Console.WriteLine("Using MSI credentials");
credentials = new ManagedIdentityCredential(msiClientId);
}
- Tons of features like Key Vault refs don’t work (“Key Vault references currently only support system-assigned managed identities. User-assigned identities cannot be used.”, see https://docs.microsoft.com/en-us/azure/app-service/app-service-key-vault-references).
Proposal
Support MSI_CLIENT_ID
env variable or repurpose existing AZURE_CLIENT_ID
.
We can set this in App Settings, either during terraform, or during deployment. If MSI_CLIENT_ID
is set, the library will use client id specified there when getting MSI token.
For example, add support for env var here: https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/identity/Azure.Identity/src/EnvironmentVariables.cs#L19
internal class EnvironmentVariables
{
// Either reuse this.
public static string ClientId => Environment.GetEnvironmentVariable("AZURE_CLIENT_ID");
// ...
public static string MsiEndpoint => Environment.GetEnvironmentVariable("MSI_ENDPOINT");
public static string MsiSecret => Environment.GetEnvironmentVariable("MSI_SECRET");
// Or add this.
public static string MsiClientId => Environment.GetEnvironmentVariable("MSI_CLIENT_ID");
}
Here is how the code might look here: https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/identity/Azure.Identity/src/AppServiceV2017ManagedIdentitySource.cs#L54
protected override Request CreateRequest(string[] scopes)
{
// covert the scopes to a resource string
string resource = ScopeUtilities.ScopesToResource(scopes);
Request request = Pipeline.HttpPipeline.CreateRequest();
request.Method = RequestMethod.Get;
request.Headers.Add("secret", _secret);
request.Uri.Reset(_endpoint);
request.Uri.AppendQuery("api-version", AppServiceMsiApiVersion);
request.Uri.AppendQuery("resource", resource);
if (!string.IsNullOrEmpty(_clientId))
{
request.Uri.AppendQuery("clientid", _clientId);
}
// Add a couple of extra else ifs.
else if (!string.IsNullOrEmpty(EnvironmentVariables.MsiClientId))
{
// Use client id from env var if present.
request.Uri.AppendQuery("clientid", EnvironmentVariables.MsiClientId);
}
else if (!string.IsNullOrEmpty(EnvironmentVariables.ClientId))
{
// Repurpose exisitng AZURE_CLIENT_ID if present.
request.Uri.AppendQuery("clientid", EnvironmentVariables.ClientId);
}
return request;
}
Benefits
- Uniform workflow regardless of auth method, works both locally and in Azure transparently.
- Setting
MSI_CLIENT_ID
orAZURE_CLIENT_ID
is easy via App Settings. It is terraformable, or easy to set during deployments. The use ofAZURE_CLIENT_ID
is already supported and documented, so this change will not be out of line. - Other features like Key Vault references may start to work with User Assigned Identities, if they use
Azure.Identity
library under the hood.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:7
- Comments:8 (4 by maintainers)
Top GitHub Comments
@ppanyukov Normally for a feature request like this we’d ask for this to be filed on our uservoice, but I actually don’t see that item already filed, strangely. That said, we do have support for it lined up to be available very soon. I can’t give a specific timeline, but it shouldn’t be too much longer.
Thanks for clarifying. To your follow up question:
This appears to be a documentation oversight. I’ll file an issue to get the docs updated.
Thanks for pointing this out!