Verify Image Signature
How to Verify Image Signatures
Starting with DSF 2.1.0, all official Docker images published to ghcr.io/datasharingframework are signed using Cosign with keyless signing backed by GitHub's OIDC identity provider. Each image additionally has a CycloneDX SBOM attached to the registry, which is signed the same way.
Verifying signatures before pulling images into production is strongly recommended. It ensures that the image was built and published by the official DSF GitHub Actions release workflow and has not been tampered with.
Prerequisites
Cosign v2.0 or newer installed on the host running the verification.
Network access to
ghcr.ioand the public Sigstore transparency log (rekor.sigstore.dev).The exact image digest (
sha256:...) of the image you want to verify. The digest can be looked up on the GitHub package page of the respective image or via:docker buildx imagetools inspect ghcr.io/datasharingframework/<image>:<tag>
Always pin the digest
Verifying by tag alone (:2.1.0) is not sufficient — tags can be reassigned. Always include the immutable @sha256:<digest> in the verification command and in your production docker-compose.yml.
Verify the Image Signature
A successful verification prints the verified claims to stdout and exits with status 0. The certificate identity confirms the signature was created by a workflow inside the datasharingframework/dsf repository, the OIDC issuer confirms it was a GitHub Actions run.
The commands below are pre-filled with the correct image tag for this release. Replace <digest> with the digest you looked up for the image you intend to deploy.
FHIR Server (fhir)
cosign verify \
ghcr.io/datasharingframework/fhir:2.1.0@sha256:71599af143f0262a7265aa2bc4ea5a9660f11de6248a053e060b5667070203fd \
--certificate-identity-regexp "https://github.com/datasharingframework/dsf/.*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"FHIR Reverse Proxy (fhir_proxy)
cosign verify \
ghcr.io/datasharingframework/fhir_proxy:2.1.0@sha256:9f11a3580c970314532f5951808be6fe72f1de7d53348e625d2dd0c95bcf1d96 \
--certificate-identity-regexp "https://github.com/datasharingframework/dsf/.*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"BPE Server (bpe)
cosign verify \
ghcr.io/datasharingframework/bpe:2.1.0@sha256:3ee7ef0ac201fc3776273fbfc2569bdc4edf724a2bb9f1b4a889eb7e13ff4049 \
--certificate-identity-regexp "https://github.com/datasharingframework/dsf/.*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"BPE Reverse Proxy (bpe_proxy)
cosign verify \
ghcr.io/datasharingframework/bpe_proxy:2.1.0@sha256:c67da4a1720ea75a383764db2bf25619fe70f57773b1069029f5b49588eb1ecc \
--certificate-identity-regexp "https://github.com/datasharingframework/dsf/.*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"Verify the SBOM Attestation
Each image has a signed CycloneDX SBOM attached. Substitute <image> with one of fhir, fhir_proxy, bpe, bpe_proxy and <digest> with the digest of the image you are verifying:
cosign verify-attestation \
--type cyclonedx \
ghcr.io/datasharingframework/<image>:2.1.0@sha256:<digest> \
--certificate-identity-regexp "https://github.com/datasharingframework/dsf/.*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"To extract the SBOM payload for further processing (e.g. dependency or vulnerability analysis):
cosign download attestation \
--predicate-type https://cyclonedx.org/bom \
ghcr.io/datasharingframework/<image>:2.1.0@sha256:<digest> \
| jq -r .payload | base64 -d | jq .predicate > sbom.cdx.jsonTroubleshooting
no matching signatures— The image was not signed by the official DSF release workflow. Do not use it in production. Re-check the registry path (ghcr.io/datasharingframework/...) and the digest.certificate identity ... did not match— The signature exists but was produced by a different repository or workflow. Verify you are pulling from the officialdatasharingframework/dsforg.- Network errors against
rekor.sigstore.dev— Cosign queries the public transparency log during verification. In air-gapped environments, pre-fetch and cache the log entries, or run cosign with--insecure-ignore-tlog=trueonly after carefully assessing the security implications.