Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use Docker Registry HTTP API V2 to obtain a list of all repositories in Docker Hub?

An external organization that I work with has given me access to a private (auth token protected) docker registry, and eventually I would like to be able to query this registry, using docker's HTTP API V2, in order to obtain a list of all the repositories and/or images available in the registry.

But before I do that, I'd first like to get some basic practice with constructing these types of API queries on a public registry such as Docker Hub. So I've gone ahead and registered myself with a username and password on Docker Hub, and also consulted the API V2 documentation, which states that one may request an API version check as:

GET /v2/

or request a list of repositories as:

GET /v2/_catalog

Using curl, together with the username and password that I used in order to register my Docker Hub account, I attempt to construct a GET request at the command line:

stachyra> curl -u stachyra:<my_password> -X GET https://index.docker.io/v2/
{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":null}]}
stachyra> curl -u stachyra:<my_password> -X GET https://index.docker.io/v2/_catalog
{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"registry","Class":"","Name":"catalog","Action":"*"}]}]}

where of course, in place of <my_password>, I substituted my actual account password.

The response that I had been expecting from this query was a giant json message, listing thousands of repository names, but instead it appears that the API is rejecting my Docker Hub credentials.

Question 1: Do I even have the correct URL (index.docker.io) for the docker hub registry? (I made this assumption in the first place based upon the status information returned by the command line tool docker info, so I have good reason to think it's correct.)

Question 2: Assuming I have the correct URL for the registry service itself, why does my query return an "UNAUTHORIZED" error code? My account credentials work just fine when I attempt to login via the web at hub.docker.com, so what's the difference between the two cases?

like image 411
stachyra Avatar asked Sep 12 '25 07:09

stachyra


1 Answers

Do I even have the correct URL

  • "Docker" is a protocol, "DockerHub" is product that implements the Docker protocol but is not limited to it. Docker APIs are also implemented by other providers like:
    • GitLab (registry.gitlab.com)
    • GitHub CR (ghcr.io)
    • GCP GCR (gcr.io)
    • AWS ECR (public.ecr.aws & <account_id>.dkr.ecr..amazonaws.com)
    • Azure ACR (<registry_name>.azurecr.io)
  • index.docker.io hosts the Docker implementation by DockerHub.
  • hub.docker.com hosts the rich DockerHub specific APIs.
  • NOTE: DockerHub implements the generic Docker HTTP API V2 but it doesn't implement _catalog API from the generic API set.

why does my query return an "UNAUTHORIZED" error code?

In order to use the Docker V2 API, a JWT auth token needs to be generated from https://auth.docker.io/token for each call and that token has to be used as Bearer token in the DockerHub calls at index.docker.io

When we hit the DockerHub APIs like this: https://index.docker.io/v2/library/alpine/tags/list, it returns 401 with info on the missing pre-flight auth call. We look for www-authenticate response header in the failed request.

eg: www-authenticate: Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:library/alpine:pull",error="invalid_token"

This means, we need to explicitly call following API to obtain the auth token.

https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/alpine:pull

The https://auth.docker.io/token works without any auth for public repos. To access a private repo, we need to add basic http auth to the request.

https://<username>:<password>@auth.docker.io/token?service=registry.docker.io&scope=repository:<repo>:pull

NOTE: auth.docker.io will generate a token even if the request is not valid (invalid creds or scope or anything). To validate the token, we can parse the JWT (eg: from jwt.io) and check access field in the payload, it should be containing requested scope references.

like image 52
Kanak Singhal Avatar answered Sep 15 '25 03:09

Kanak Singhal