Sunday, October 30, 2022

[SOLVED] How can I use the Docker Registry API to pull information about a container? Getting UNAUTHORIZED

Issue

I came across an article awhile back titled Inspecting Docker Images without pulling them that gets into the nitty-gritty of the specific API calls needed to essentially do a docker inspect with REST calls. However, I'm wondering if perhaps something has changed with the Docker registry API since that article was written.

The article breaks down that you need to make three REST calls, in order, to get information about a container. In the case of the public Docker registry, they are as follows:

  1. A GET request to auth.docker.io to get a token

    curl "https://auth.docker.io/token?scope=repository:<image>:pull&service=registry.docker.io"
    

    In this case image could be something like nginx or docker - basically whatever image you're looking up. This REST call returns a token to use in subsequent requests.

  2. A GET request to retrieve the manifest listings

    curl -H "Accept: application/vnd.docker.distribution.manifest.v2+json"
    -H "Authorization: Bearer <token-from-step-1>"
    "https://registry-1.docker.io/v2/<image>/manifests/<tag>"
    

    Here image is the same as in Step 1, and tag could be something like latest. This call returns some JSON; the key is that we need to extract the value at .config.digest. This is the digest string that we use in the final request.

  3. Finally a GET request to retrieve the container config, using the digest we received in step 2

    curl -H "Accept: application/vnd.docker.distribution.manifest.v2+json"
    -H "Authorization: Bearer <token-from-step-1>"
    "https://registry-1.docker.io/v2/<image>/blobs/<digest-from-step-2>"
    

    This returns some JSON, and the field I care about is .config

I was able to test this successfully on a private Docker registry, although there I had to do something different for auth. However I have the opposite problem when I try to follow along with the guide (which I've outlined in these steps above) for the public Docker registry: Step 1 gives me a token, but that token is worthless. Whenever I try to use it, in Steps 2 or 3, I get this back:

{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"repository","Class":"","Name":"docker","Action":"pull"}]}]}

Any ideas on how to get this working?


Solution

Using the following steps you can retrieve the configuration of any public container-image.

  1. Get the respective token for the image. Note that you must specify the full name of the image (official images use the library repository). Thereby, the NGINX image should be referred to as: library/nginx.

    curl \
        --silent \
        "https://auth.docker.io/token?scope=repository:library/nginx:pull&service=registry.docker.io" \
        | jq -r '.token'
    

    Token shortened for brevity: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXV...

  2. Retrieve the image digest from the manifest. For this request, you also need to specify a valid tag (this example uses the latest tag).

    curl \
        --silent \
        --header "Accept: application/vnd.docker.distribution.manifest.v2+json" \
        --header "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXV..." \
        "https://registry-1.docker.io/v2/library/nginx/manifests/latest" \
        | jq -r '.config.digest'
    

    sha256:2bcb04bdb83f7c5dc30f0edaca1609a716bda1c7d2244d4f5fbbdfef33da366c

  3. Finally, get the container configuration by using the following request. Within the URL, the digest from step two must be specified.

    curl \
        --silent \
        --location \
        --header "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXV..." \
        "https://registry-1.docker.io/v2/library/nginx/blobs/sha256:2bcb04bdb83f7c5dc30f0edaca1609a716bda1c7d2244d4f5fbbdfef33da366c" \
        | jq -r '.container_config'
    

    Output shortened for brevity:

    {
        "Hostname": "6c02a05b3d09",
        "Env": [
            "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
            "NGINX_VERSION=1.15.10-1~stretch",
            "NJS_VERSION=1.15.10.0.3.0-1~stretch"
        ],
        "Labels": {
            "maintainer": "NGINX Docker Maintainers <[email protected]>"
        },
        "StopSignal": "SIGTERM"
    }
    


Answered By - prd
Answer Checked By - Marilyn (WPSolving Volunteer)