azure-sdk-for-net
azure-sdk-for-net copied to clipboard
[FEATURE REQ] Expose IdentityToken from ACR client
Library name
Azure Identity
Please describe the feature.
Azure Identity should provide a way to retrieve an ACR refresh token after creating an ACR client using an AAD/MSI token.
Thank you for your feedback. Tagging and routing to the team member best able to assist.
@kaitlynyang Can you please share your scenario a little bit more? What do you intend to do with the refresh token? Would you rather want that scenario from the ACR SDK instead?
@pallavit Sure -- so we are trying to enable Docker authentication using an MSI and we've confirmed that we're able to do this with the correct token. However, currently when we use the Identity SDK we are only able to retrieve an AAD token rather than the refresh token needed to authenticate to ACR. We're looking for a way to get this refresh token to use with the Docker client
The first step here is to see if this is something we can quickly expose by sharing a sample. I have been OOF this week on jury duty, but I will plan to look at this next week. If it is not something we can currently do, we should evaluate as a feature crew if this is functionality we want to expose in the SDK.
Hi @kaitlynyang --
As we discussed offline, the Azure.Containers.ContainerRegistry package implements the ACR authentication flow described in the ACR integration with AAD documentation. Specifically, this happens in the ContainerRegistryChallengeAuthenticationPolicy, and a description of the flow implementation is provided in the policy's summary comments.
Since this authentication flow is specific to the ACR service, it is not something that we would provide in the Azure.Identity library, but you can use the ContainerRegistryClient to access this functionality by adding a custom policy to the client's pipeline. You could also take the implementation in ContainerRegistryChallengeAuthenticationPolicy and adapt it to your needs.
var options = new ContainerRegistryClientOptions() { Audience = ContainerRegistryAudience.AzureResourceManagerPublicCloud };
InterceptPolicy interceptPolicy = new InterceptPolicy();
options.AddPolicy(interceptPolicy, HttpPipelinePosition.PerRetry);
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, credential, options);
var repositoryClient = await client.GetRepository("<any-repository>").GetPropertiesAsync();
// The following line gives you access to the final request in the sequence.
var request = interceptPolicy.Request;
public class InterceptPolicy : HttpPipelinePolicy
{
public Request? Request;
public override void Process(HttpMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline)
{
ProcessNext(message, pipeline);
Request = message.Request;
}
public override async ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline)
{
await ProcessNextAsync(message, pipeline);
// The following line will access each request in the sequence.
// The service's response is also available as a property on message.
Request = message.Request;
}
}
You may need to change the specific call you make to the service to use the correct challenge scope.
@schaabs, please let us know if you have any concerns regarding using this approach to access these tokens. @lmolkova, @pallavit FYI
Hi, we're sending this friendly reminder because we haven't heard back from you in 7 days. We need more information about this issue to help address it. Please be sure to give us your input. If we don't hear back from you within 14 days of this comment the issue will be automatically closed. Thank you!
Hi @annelo-msft, are you suggesting to parse the HTTP request to extract the refresh token in that matter, using what's already available in the ContainerRegistryClient implementation? We've validated that using the ContainerRegistryClient we can obtain the ACR refresh token that we need, and we had previously discussed the possibility of exposing this token through the SDK. Is that not a preferred solution in this case / are there any concerns with using an InterceptPolicy instead?
Hi @kaitlynyang --
Yes, we had discussed offline several possibilities for you to get access to an implementation of the authentication flow for ACR, since you are using an SDK that is not supported by the Azure SDK team.
- You could reuse the source for the auth flow implementation in ContainerRegistryChallengeAuthenticationPolicy to retrieve the token your SDK needs.
- You could use the ContainerRegistryClient and modify the pipeline as shown in the sample to obtain the token. Once you have the
Requestinstance in hand, you shouldn't need to parse anything to retrieve the token from the header value, just callrequest.Headers.TryGetValue(). @schaabs, do you have any concerns with this approach? My assumption was that as long as this value stays in-memory and isn't persisted to disk anywhere, this would be reasonable, but please correct me if I am wrong. I cannot make any claims regarding the safety of the other SDK library you are using. - The Azure SDK team could look into a first-class API for supporting this functionality. This will take more time and planning, so if either of the first two approaches are sufficient for your purposes, they would meet your needs more quickly, and it would be helpful for us to know for our planning.
Regarding the third approach, @schaabs provided CommunicationIdentityClient as something we could consider emulating for a separate STS client if we decided to go with that approach.
I think either of the first two approaches would suffice as a reasonable workaround for obtaining a token from the ACR STS, until first class support is added to the library. As @annelo-msft mentioned the way we would likely add support for this would be to add another client to the library to allow applications to directly obtain ACR STS tokens for flows using clients or tools outside our library. This is a pattern we have used in other libraries across the Azure SDK for services which have a custom STS, and we would likely follow that pattern here.
Hi, we're sending this friendly reminder because we haven't heard back from you in 7 days. We need more information about this issue to help address it. Please be sure to give us your input. If we don't hear back from you within 14 days of this comment the issue will be automatically closed. Thank you!
Keeping this open per tracking customer need and requests for this feature.
Hi @kaitlynyang, we're sending this friendly reminder because we haven't heard back from you in 7 days. We need more information about this issue to help address it. Please be sure to give us your input. If we don't hear back from you within 14 days of this comment the issue will be automatically closed. Thank you!
Hi @annelo-msft, just chiming in to let you know we'd like this feature to be added as well.
On the .NET Containers team, we use a .NET app in a Docker container to orchestrate the official .NET container image builds. We're migrating to Managed Identity, and we're trying to authenticate Docker-in-Docker in order to make this scenario continue to work.
Our current plan is to use the Azure SDK to retrieve an AAD token, which we can then use to get an ACR access token via Oauth2 as described in this documentation that you linked above. Another option would be to use the az CLI in the container to run az acr login, but the az CLI adds a lot of size to our Docker image which we want to avoid if possible.
All of this would be much simpler if we could use the Azure SDK directly to get an ACR access token using MSI 🙂
@pallavit, @sandeep-sen FYI per the comment above.
@lbussell -- to clarify, are you using the .NET Azure SDK to communicate with the ACR service? If you do, I believe it will handle the token flow for you.
@lbussell -- to clarify, are you using the .NET Azure SDK to communicate with the ACR service? If you do, I believe it will handle the token flow for you.
@annelo-msft Yes, we are using the Azure SDK to communicate with our ACR, but we also need to authenticate our Docker CLI in order to pull, build, and push images from our container.
We build our images using a Docker installation inside a container (so we can control our dependencies and the Docker client version). Managed Identity works fine inside the container, but the Docker CLI (inside the build container) still requires a username/password to authenticate to our ACR. The Docker CLI itself doesn't do anything special with Managed Identity.
We'd like to get the ACR token directly from the Azure SDK to authenticate with Docker since, from my understanding, that's what it's doing internally anyways (https://github.com/Azure/acr/blob/main/docs/AAD-OAuth.md#getting-credentials-programmatically). We don't want to manage the OAuth flow and refreshing tokens ourselves if we don't have to.
There's other documentation about using the az CLI to do this (https://learn.microsoft.com/en-us/azure/container-registry/container-registry-authentication?tabs=azure-cli#az-acr-login-with---expose-token) but we'd like to avoid that for container image size reasons.