SEANK.H.LIAO

oci image to digest

immutable everything

image tag to digest

Container images are usually referenced by tag, maybe a nice semantic version, or maybe a git commit sha. Whatever the value, a tag is still a mutable thing, today it might point at one thing, a force push later, and tomorrow it points at something else.

To get around that we can reference images (or other artifacts) by digest, a content hash which can only refer to a single thing. To resolve a mutable tag to a digest, we have several options:

crane

crane, or the gcrane variant, are command line tools for general registry/image manipulation.

1$ gcrane digest golang:alpine
2sha256:ee2f23f1a612da71b8a4cd78fec827f1e67b0a8546a98d257cca441a4ddbebcb

cosign

cosign is a tool primarily for signing images/artifacts, but it notably complains if you try to sign things by tag, as you might not be signing the thing you thought you were signing. It has a triangulate subcommand for finding where the signature might be, but we can use that to extract the digest.

1$ cosign triangulate golang:alpine
2index.docker.io/library/golang:sha256-ee2f23f1a612da71b8a4cd78fec827f1e67b0a8546a98d257cca441a4ddbebcb.sig
3
4$ cosign triangulate golang:alpine | tr ':-' '@:' | sed 's/\.sig//'
5index.docker.io/library/golang@sha256:ee2f23f1a612da71b8a4cd78fec827f1e67b0a8546a98d257cca441a4ddbebcb
6
7$ cosign triangulate golang:alpine | sed -E 's/.*sha256-(.*).sig/\1/'
8ee2f23f1a612da71b8a4cd78fec827f1e67b0a8546a98d257cca441a4ddbebcb

docker

docker... just remember to pull the image first, since it operates locally instead of directly on remote registries like crane and cosign.

1$ docker image inspect golang:alpine | jq -r '.[] | .RepoDigests[]'
2golang@sha256:ee2f23f1a612da71b8a4cd78fec827f1e67b0a8546a98d257cca441a4ddbebcb