New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Built docker image/manifest digest is not exposed to image signing step, leading to potential race condition vulnerability #3496
Comments
interesting, I had the impression cosign wouldn't pull the image if its already present, though... do you have a doc/code link confirming that? if thats what happens, I'm all in for looking into this. |
This issue describes the race condition: sigstore/cosign#2047 |
One downside of the |
Unfortunately |
I think we can literally run |
From my tests, |
hmm, understood, so right now, nothing we can do here, right? maybe worth adding a note to our docs about it? |
Actually, the digest should be fetched from the output of
This would also force fixing the |
hmmm that does not seem too bad @gal-legit... 100% doable, I think! |
Good catch, I missed that docker push has the digest in the output. I wonder whether that's an API contract though, or if multiple digests could ever show up in the output?
|
I failed to find documentation about it for the docker client, yet IMO it's pretty safe to assume that it won't change because:
AFAIK, the only case that it might happen is by using the p.s. you can use |
I double checked -- the Seems okay to parse that output since it's so much simpler than the alternative. For manifest pushes, the |
Extract the digest (sha256) of docker images from the `docker push` command for dockers published to the docker registry. Outputting the digest is required to avoid a race condition when referencing the image, where the image tag is being modified before the reference is done. See this [blog post](#3496) for more info. This PR fixes #3496. Note that the 'publish' pipe now must run before the 'metadata' pipe, so that the information extracted during the 'publish' pipe would appear in the metadata. Previously, the published docker images metadata wasn't printed (because of the order). It made sense because the content of the published image was just a subset of the local one. Now that it is printed to the metadata, it should have a different name to avoid confusion. As I mentioned, it wasn't printed before - so there shouldn't be any backward-compatibility issues. --- Local tests: ``` go test -v . === RUN TestVersion === RUN TestVersion/only_version === RUN TestVersion/version_and_date === RUN TestVersion/version,_date,_built_by === RUN TestVersion/all_empty === RUN TestVersion/complete --- PASS: TestVersion (0.00s) --- PASS: TestVersion/only_version (0.00s) --- PASS: TestVersion/version_and_date (0.00s) --- PASS: TestVersion/version,_date,_built_by (0.00s) --- PASS: TestVersion/all_empty (0.00s) --- PASS: TestVersion/complete (0.00s) PASS ok github.com/goreleaser/goreleaser 0.764s ``` Output example: ``` { "name": "gallegit/hello-world:latest", "path": "gallegit/hello-world:latest", "goos": "linux", "goarch": "amd64", "internal_type": 10, "type": "Published Docker Image", "extra": { "digest": "sha256:c3f7dd196a046dc061236d3c6ae1e2946269e90da30b0a959240ca799750e632" } } ``` Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> Co-authored-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
I don't think #3540 fully closes this issue. We still need support for extracting the pushed manifest digest and to wire the digest into the sign pipeline around here: goreleaser/internal/pipe/sign/sign.go Line 156 in ee6225f
|
ah, right |
@ethan-lowman-dd #3556 and #3555 should take care of the remaining parts |
this drives it home by using the actual images/manifest digests to sign with cosign by default. the default signing command is changing in this PR, but since `digest` should be always there (if not, the pipeline will fail way earlier), it should be fine. refs #3496 refs #3540 Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com>
refs #3496 Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com>
should be good now |
thanks everyone! |
Is your feature request related to a problem? Please describe.
Currently, the Docker image digest built by
dockers: ...
is not exposed todocker_signs: ...
in the environment variables. If the image tag in the registry is modified after pushing and before signing, signer tools that re-pull an image to sign it (includingcosign
) will potentially sign an image different from the one that was produced by goreleaser.Describe the solution you'd like
Docker exposes the
--metadata-file
flag todocker build
yields a file that looks like this in thegoreleaserdocker
temp dir:If we expose this built digest to the
docker_signs
tools via an environment variableartifactDigest
, users would have the ability to pass the digest to the signing tool and avoid any chance of a race condition. In my opinion, this should be the default behavior.Describe alternatives you've considered
Assuming you're using a tool like
cosign
that takes an image as an argument, you can fetch the digest from the local Docker daemon and pass that to the signer tool like so:I'm not 100% sure this is actually correct though --
docker inspect
returns a list of digests for a given tag, which suggests there may be conditions in which multiple digests are returned for a single tag in the Docker daemon's image store. I couldn't find any such case in a quick code search of Docker, however.This is quite a hack and it should be easier to avoid the race condition.
Search
Code of Conduct
Additional context
--metadata-file
to thedocker build
command viabuild_flag_templates
, it may not be possible to reliably extract the digest from the docker build.The text was updated successfully, but these errors were encountered: