Azure / acr

Azure Container Registry samples, troubleshooting tips and references
https://aka.ms/acr
Other
164 stars 112 forks source link

Using Tokens from an Azure Container Registry to Call the /_tags Endpoint #676

Closed justinW859 closed 1 year ago

justinW859 commented 1 year ago

I have generated an access token for my Azure Container Registry (ACR) using the Token Menu. I would like to use this access token to call the /_tags endpoint for a specific image in the registry, but I am not sure how to do this.

I can use the token to login using the docker login command in powershell, but the only way I've been able to get the api call to work is by using the admin account credentials.

I thought maybe the "Action" was a clue so I created a custom scope map for the Token that explicitly included "metadata_read" but that didn't help.

this question on stackoverflow

The error I get back:

    {
        "errors": [
            {
                "code": "UNAUTHORIZED",
                "message": "authentication required, visit https://aka.ms/acr/authorization for more information.",
                "detail": [
                    {
                        "Type": "repository",
                        "Name": "my-image",
                        "Action": "metadata_read"
                    }
                ]
            }
        ]
    }

To Reproduce the error.

  1. Create a Token with metadata_read/content_read permissions scope map.
  2. GET https://registry.azurecr.io/acr/v1/my-image/_tags -- with basic auth using the username and password from the Token.

Expected Output This works fine with admin credentials. I would expect a Token having the proper permissions should function the same.

terencet-dev commented 1 year ago

Hi @justinW859,

Please open a support ticket with our team to investigate as this board is primarily used to provide roadmap updates. If you don’t have any additional questions here, this issue will close in 7 days. Thanks!

justinW859 commented 1 year ago

I will add a support ticket, but quick question, is the service supposed to work in the way I'm trying to use it?

DuckScapePhilip commented 1 year ago

Did anybody find a response to this? Seems like a bug.

justinW859 commented 1 year ago

@DuckScapePhilip No, I haven't received a response. I had done some more digging a while ago (unfortunately can't find the reference now) and there are tickets for this "feature" but its priority had been demoted. I agree, this seems like a bug and a potential security risk. The only way to get the meta-data for a repository is to use the admin account.

marchueff commented 1 year ago

I ran into the same issue today. So it seems like the bug still exists

cegraybl commented 1 year ago

For this to work you would need to call the oauth2/token API with the token user/pass and select the scope as repository:my_image:metadata_read (or *) and use the resulting bearer token to call /_tags/. The issue here is that for the service it will try to use the "Basic Auth" from the token user/pass on the /_tags/ API it will attempt to auth you via ARM (as if it was an SPN) so it will fail.

marchueff commented 1 year ago

@cegraybl Very good hint! Can confirm that this works. Here is a bit more detailed explanation: https://azure.github.io/acr/Token-BasicAuth.html#using-the-token-api

So, you can request a bearer token with a GET to https://myregistry.azurecr.io/oauth2/token?service=myregistry.azurecr.io&scope=repository:myimage:metadata_read with token username and password provided with Basic Auth.

Then you can utilize the bearer token in requests to registry endpoints, e.g. /acr/v1/roc/_tags or /v2/manifests/myimage/latest

justinW859 commented 1 year ago

For this to work you would need to call the oauth2/token API with the token user/pass and select the scope as repository:my_image:metadata_read (or *) and use the resulting bearer token to call /_tags/. The issue here is that for the service it will try to use the "Basic Auth" from the token user/pass on the /_tags/ API it will attempt to auth you via ARM (as if it was an SPN) so it will fail.

This is the solution. I had tried the oauth2 but I wasn't using the proper scope for the request, so I thought it was a dead end. I'm going to close the issue.