cosign: cosign sign does not use local image registry credentials
Question
I’m trying to sign a container image that I pushed to docker.io. This seems simple enough:
$ cosign sign -key cosign.key docker.io/adambkaplan/ruby-ex
However, when trying to pull the image, cosign does not appear to use my local credentials. Instead cosign appears to do the following:
- Try to GET the root of the container registry
- With the UNAUTHORIZED response, then it requests a “pull” scoped token
- After receiving the token, it then tries to pull the container image. For whatever reason the token is invalid, and the pull fails.
I was able to verify that my ~/.docker/config.json contains valid auth credentials for docker.io, and that I can pull images using those credentials with my container engine (podman).
This could be related to #337.
Here’s the debug output:
cosign -d sign -key cosign.key docker.io/adambkaplan/ruby-ex
2021/08/27 10:46:56 --> GET https://index.docker.io/v2/
2021/08/27 10:46:56 GET /v2/ HTTP/1.1
Host: index.docker.io
User-Agent: Go-http-client/1.1
Accept-Encoding: gzip
2021/08/27 10:46:56 <-- 401 https://index.docker.io/v2/ (201.76705ms)
2021/08/27 10:46:56 HTTP/1.1 401 Unauthorized
Content-Length: 87
Content-Type: application/json
Date: Fri, 27 Aug 2021 14:46:56 GMT
Docker-Distribution-Api-Version: registry/2.0
Strict-Transport-Security: max-age=31536000
Www-Authenticate: Bearer realm="https://auth.docker.io/token",service="registry.docker.io"
{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":null}]}
2021/08/27 10:46:56 --> GET https://auth.docker.io/token?scope=repository%3Aadambkaplan%2Fruby-ex%3Apull&service=registry.docker.io [body redacted: basic token response contains credentials]
2021/08/27 10:46:56 GET /token?scope=repository%3Aadambkaplan%2Fruby-ex%3Apull&service=registry.docker.io HTTP/1.1
Host: auth.docker.io
User-Agent: go-containerregistry/v0.6.0
Accept-Encoding: gzip
2021/08/27 10:46:57 <-- 200 https://auth.docker.io/token?scope=repository%3Aadambkaplan%2Fruby-ex%3Apull&service=registry.docker.io (179.251563ms) [body redacted: basic token response contains credentials]
2021/08/27 10:46:57 HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: application/json
Date: Fri, 27 Aug 2021 14:46:56 GMT
Strict-Transport-Security: max-age=31536000
2021/08/27 10:46:57 --> GET https://index.docker.io/v2/adambkaplan/ruby-ex/manifests/latest
2021/08/27 10:46:57 GET /v2/adambkaplan/ruby-ex/manifests/latest HTTP/1.1
Host: index.docker.io
User-Agent: go-containerregistry/v0.6.0
Accept: application/vnd.docker.distribution.manifest.v1+json,application/vnd.docker.distribution.manifest.v1+prettyjws,application/vnd.docker.distribution.manifest.v2+json,application/vnd.oci.image.manifest.v1+json,application/vnd.docker.distribution.manifest.list.v2+json,application/vnd.oci.image.index.v1+json
Authorization: <redacted>
Accept-Encoding: gzip
2021/08/27 10:46:57 <-- 401 https://index.docker.io/v2/adambkaplan/ruby-ex/manifests/latest (43.68461ms)
2021/08/27 10:46:57 HTTP/1.1 401 Unauthorized
Content-Length: 162
Content-Type: application/json
Date: Fri, 27 Aug 2021 14:46:57 GMT
Docker-Distribution-Api-Version: registry/2.0
Strict-Transport-Security: max-age=31536000
Www-Authenticate: Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:adambkaplan/ruby-ex:pull",error="insufficient_scope"
{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"repository","Class":"","Name":"adambkaplan/ruby-ex","Action":"pull"}]}]}
2021/08/27 10:46:57 --> GET https://auth.docker.io/token?scope=repository%3Aadambkaplan%2Fruby-ex%3Apull&service=registry.docker.io [body redacted: basic token response contains credentials]
2021/08/27 10:46:57 GET /token?scope=repository%3Aadambkaplan%2Fruby-ex%3Apull&service=registry.docker.io HTTP/1.1
Host: auth.docker.io
User-Agent: go-containerregistry/v0.6.0
Accept-Encoding: gzip
2021/08/27 10:46:57 <-- 200 https://auth.docker.io/token?scope=repository%3Aadambkaplan%2Fruby-ex%3Apull&service=registry.docker.io (38.934215ms) [body redacted: basic token response contains credentials]
2021/08/27 10:46:57 HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: application/json
Date: Fri, 27 Aug 2021 14:46:57 GMT
Strict-Transport-Security: max-age=31536000
2021/08/27 10:46:57 --> GET https://index.docker.io/v2/adambkaplan/ruby-ex/manifests/latest
2021/08/27 10:46:57 GET /v2/adambkaplan/ruby-ex/manifests/latest HTTP/1.1
Host: index.docker.io
User-Agent: go-containerregistry/v0.6.0
Accept: application/vnd.docker.distribution.manifest.v1+json,application/vnd.docker.distribution.manifest.v1+prettyjws,application/vnd.docker.distribution.manifest.v2+json,application/vnd.oci.image.manifest.v1+json,application/vnd.docker.distribution.manifest.list.v2+json,application/vnd.oci.image.index.v1+json
Authorization: <redacted>
Accept-Encoding: gzip
2021/08/27 10:46:57 <-- 401 https://index.docker.io/v2/adambkaplan/ruby-ex/manifests/latest (40.460773ms)
2021/08/27 10:46:57 HTTP/1.1 401 Unauthorized
Content-Length: 162
Content-Type: application/json
Date: Fri, 27 Aug 2021 14:46:57 GMT
Docker-Distribution-Api-Version: registry/2.0
Strict-Transport-Security: max-age=31536000
Www-Authenticate: Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:adambkaplan/ruby-ex:pull",error="insufficient_scope"
{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"repository","Class":"","Name":"adambkaplan/ruby-ex","Action":"pull"}]}]}
error: signing docker.io/adambkaplan/ruby-ex: getting remote image: GET https://index.docker.io/v2/adambkaplan/ruby-ex/manifests/latest: UNAUTHORIZED: authentication required; [map[Action:pull Class: Name:adambkaplan/ruby-ex Type:repository]]
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 29 (12 by maintainers)
Hi, had auth issues (I use podman instead of docker), the following was a workaround for me:
cat ${XDG_RUNTIME_DIR}/containers/auth.json > ~/.docker/config.jsonMy two cents:
auth.json(podman) orconfig.json(docker) must contain an entry with authentications forhttps://index.docker.io/v1/otherwise the authentication seems to fail. I have solved it by adding an extra entry like so (trailing / needed):I found out that if the registry URL is
index.docker.iogo-containerregistry uses the full url when looking for creds.In my case, I discovered that this .docker/config.json results in authentication failure:
But this one results in success:
Interestingly the authentication failure when
/v1is not appended clearly shows that/v2/is attempted by default:@tommyreilly you’re right, it only supports
docker’s behavior right now.If we end up supporting some alternative to Docker’s configuration and authentication scheme, it should be one we maintain. I think documenting our
dockermimicry and prescribing a manual way of setting things up for automation should suffice for nowNot a daemon, just the normal docker config file behavior; i.e.
$HOME/.docker/config.jsonbut it can be overridden byDOCKER_CONFIG. If Snap is moving this around but not setting that environment variable, I’d argue it’s a bug in Snap?There’s not really a registry API for logging in. We could support a
logincommand, but it just manipulates a local configuration file and wouldn’t support configuring credential helpers…I think the cosign tool and docs could probably do a better job describing how auth works, regardless.
I’m hitting this same issue when trying to integrate cosign into our teams CI flow. Any use of buildah, podman, skopeo based tools where the credentials are stored in a different location than ~/.docker, seems to have cosign not recognise the use of a different container build tool and it’s already authenticated information creds.
As these tools are commonly used in automated flows, it would be great if anyone has any ideas to work round the current situation.