acr icon indicating copy to clipboard operation
acr copied to clipboard

Respond with www-authenticate header to the token endpoint upon a 401

Open sajayantony opened this issue 2 years ago • 10 comments

Currently an incorrect basic token responds as follows

➜ curl -v https://PAT:[email protected]/v2/ 2>&1 | grep -i www
< Access-Control-Expose-Headers: WWW-Authenticate
< Www-Authenticate: Basic realm="Azure Container Registry"

As for other registries that support bearer, nudging the user to send the creds or authenticate with the bearer endpoint is desirable and ACR could return the Bearer header so that clients may follow that path.

This pattern is shown here - https://github.com/dependabot/dependabot-core/issues/3689

curl -v https://PAT:[email protected]/v2/library/golang/tags/list 2>&1 | grep -i www
< www-authenticate: Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:library/golang:pull"

sajayantony avatar Oct 10 '22 22:10 sajayantony

I heard from an acquaintance that the OCI spec may get an Auth-related spec addition in the not too distant future, hopefully this codifies what most of the other container registries are doing for Bearer auth.

jeffwidman avatar Feb 02 '23 23:02 jeffwidman

As far as I can tell this currently blocks users from using ACR with GitHub Dependabot:

# .github/dependabot.yml
registries:
  acr-docker:
    type: docker-registry
    url: https://foobar.azurecr.io
    username: dependabot-user
    password: <secret>

This fails when attempting to run the update because dependabot first tries with BasicAuth and expects to be able to use the Www-Authenticate header to upgrade to a different authentication mechanism:

updater | 2023/06/28 13:45:56 INFO <job_685545722> Starting job processing
updater | 2023/06/28 13:45:57 INFO <job_685545722> Starting update job for $repo
updater | 2023/06/28 13:45:57 INFO <job_685545722> Checking all dependencies for version updates...
updater | 2023/06/28 13:45:57 INFO <job_685545722> Checking if foo 1.35.1 needs updating
  proxy | 2023/06/28 13:45:57 [014] GET https://foobar.azurecr.io:443/v2/web/tags/list
  proxy | 2023/06/28 13:45:57 [014] * authenticating docker registry request (host: foobar.azurecr.io)
  proxy | 2023/06/28 13:45:57 [014] 401 https://foobar.azurecr.io:443/v2/web/tags/list
  proxy | 2023/06/28 13:45:57 [016] GET https://foobar.azurecr.io:443/v2/web/tags/list
  proxy | 2023/06/28 13:45:57 [016] * authenticating docker registry request (host: foobar.azurecr.io)
  proxy | 2023/06/28 13:45:57 [016] 401 https://foobar.azurecr.io:443/v2/web/tags/list
updater | 2023/06/28 13:45:57 INFO <job_685545722> Handled error whilst updating foo: private_source_authentication_failure {:source=>"foobar.azurecr.io"}
updater | 2023/06/28 13:45:58 INFO <job_685545722> Finished job processing
updater | 2023/06/28 13:45:58 INFO Results:
updater | Dependabot encountered '1' error(s) during execution, please check the logs for more details.
updater | +---------------------------------------------+
updater | |        Dependencies failed to update        |
updater | +-----+---------------------------------------+
updater | | web | private_source_authentication_failure |
updater | +-----+---------------------------------------+

privatwolke avatar Jun 28 '23 13:06 privatwolke

👋 a maintainer of :dependabot: here.

ACR should work fine with Dependabot, see details here: https://github.com/dependabot/dependabot-core/issues/3689#issuecomment-1273849197

Still be great to see this issue fixed so that the behavior is consistent with the other docker registry implementations... but it's not a blocker for using Dependabot + ACR.

jeffwidman avatar Aug 04 '23 22:08 jeffwidman

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days.

github-actions[bot] avatar Oct 11 '23 01:10 github-actions[bot]

This issue was closed because it has been stalled for 30 days with no activity.

github-actions[bot] avatar Nov 10 '23 01:11 github-actions[bot]

This issue is a blocker for our ability to use dependabot with acr despite what's written in https://github.com/dependabot/dependabot-core/issues/3689#issuecomment-1273849197. We use acr tokens with scope maps, which does not seem to support basic auth, so we see the same issues as comment https://github.com/Azure/acr/issues/651#issuecomment-1611462322.

JonasBak avatar Jan 09 '24 15:01 JonasBak

Dependabot core does work with tokens. But we can keep this open until ACR returns bearer auth. I don't think basic auth will be supported but fixing the header is reasonable.

For context here is a dry run with dependabot core and a token based authentication working. Token was given access to all repositories. btw. Is there any other kind of setup that you had in mind @JonasBak ?

W, [2024-01-10T18:30:02.957898 #41]  WARN -- : Error looking up Docker source: time="2024-01-10T18:29:56Z" level=warning msg="Sleeping for backoff" Host=dependabottest.azurecr.io Seconds=1.9999943999999998
time="2024-01-10T18:29:58Z" level=warning msg="Sleeping for backoff" Host=dependabottest.azurecr.io Seconds=3.9999945
failed to get manifest dependabottest.azurecr.io/library/alpine:3.16.1: unauthorized
 => bump library/alpine from 3.15.9 to 3.16.1

    ± Dockerfile
    ~~~
    --- /tmp/original20240110-41-5qr9hs 2024-01-10 18:30:02.957529518 +0000
    +++ /tmp/updated20240110-41-xvn64v  2024-01-10 18:30:02.957529518 +0000
    @@ -1,2 +1,2 @@
    -FROM dependabottest.azurecr.io/library/alpine:3.15.9
    +FROM dependabottest.azurecr.io/library/alpine:3.16.1
     # using a vulnerable image for testing
    ~~~
    2 insertions (+), 2 deletions (-)
🌍 Total requests made: '0'

sajayantony avatar Jan 10 '24 18:01 sajayantony

I do see that dependabot-core will work with ACR, as it does an unauthenticated request first, that will return the correct header, but I don't think the "GitHub hosted Dependabot" does the same.

From https://github.com/dependabot/dependabot-core/tree/main#private-registry-credential-management:

[...] for the Dependabot service that Github runs, we wrap Dependabot-Core with a credential proxy so those private registry secrets are never exposed to Dependabot-Core.

I might be wrong (so please correct me if I am), but my understanding is that GitHub uses something other than dependabot-core to handle authenticating requests to private registries, and it seems like (I haven't been able to verify this) that proxy does basic auth on the first request. So that request will fail, and the header will still indicate basic auth, not bearer.

JonasBak avatar Jan 11 '24 08:01 JonasBak

From what I understand from these two comments https://github.com/dependabot/dependabot-core/issues/3689#issuecomment-1272037775, https://github.com/dependabot/dependabot-core/issues/3689#issuecomment-1273849197, the "GitHub hosted Dependabot" works assuming ACR supports basic auth.

[...] However, the ACR credential paths do work via the basic auth flow. [...]

[...] for implementation simplicity we first try basic auth and then fallback bearer auth. Since ACR supports basic auth, that should work fine for us. And even if it doesn't, once they implement the bearer auth response to bad basic auth creds, then that fallback should work fine as well.

The way I read this is that:

  1. ACR returns a Www-Authenticate header indicating basic auth when you have tried using basic auth
  2. ACR doesn't support basic auth for tokens
  3. "GitHub hosted Dependabot" tries basic auth on the first request

And that because of this, it will never try bearer auth, and the authentication fails.

JonasBak avatar Jan 15 '24 09:01 JonasBak

@JonasBak I believe you are correct. I have filed a feature request with the team.

bdragon avatar Feb 07 '24 15:02 bdragon