Verifying the images¶
The Security Shepherd Tomcat image is published to Docker Hub as owasp/security-shepherd. This page shows how to check where an image came from and what's inside it, before you run it. To scan it for known vulnerabilities, see Vulnerability management.
Image tags¶
| Tag | What it is |
|---|---|
X.Y.Z, e.g. 4.0.0 |
A release. Never changes once published. |
X.Y, X, latest |
The newest release in that line. Moves with each release. |
X.Y.Z-SNAPSHOT, e.g. 4.1.0-SNAPSHOT |
The latest dev build of the version in progress. Moves with each push to dev. |
dev |
The latest dev build. Moves with each push to dev. |
Snapshot and dev images are untested pre-releases. For anything you rely on, use a release tag.
Images from 4.0.0 on, and dev and snapshot builds, run natively on linux/amd64 and linux/arm64, including Apple Silicon. The older images (3.0, 3.1, and latest until 4.0.0 is released) are linux/amd64 only, and have none of the SBOM, provenance or signature described below.
Choose the image to check¶
The commands below use these two variables, so set them first:
# A release: the tag, and the git tag it was built from
TAG=4.0.0
REF=refs/tags/4.0.0
# Or, to check a snapshot / dev build instead, uncomment these two lines
# TAG=4.0.0-SNAPSHOT
# REF=refs/heads/dev
1. Verify where it came from¶
This is the check that matters. The release workflow signs a SLSA build provenance for every image it pushes, with GitHub artifact attestations. It's signed through Sigstore and recorded in its public transparency log. You need the GitHub CLI, logged in with any GitHub account (gh auth login).
# Proves the image was built from OWASP/SecurityShepherd by its release workflow, from $REF.
# --signer-workflow rejects anything signed by another workflow, even one in this repository.
gh attestation verify "oci://docker.io/owasp/security-shepherd:$TAG" \
--repo OWASP/SecurityShepherd \
--signer-workflow OWASP/SecurityShepherd/.github/workflows/release-build.yml \
--source-ref "$REF"
# Same check, printing the whole provenance: the commit and the Actions run that built the image
gh attestation verify "oci://docker.io/owasp/security-shepherd:$TAG" \
--repo OWASP/SecurityShepherd \
--signer-workflow OWASP/SecurityShepherd/.github/workflows/release-build.yml \
--source-ref "$REF" --format json
The image is built and signed in a reusable workflow, release-build.yml, that the workflow starting the build can't change. That makes the attestation SLSA Build Level 3.
2. See what's inside it (SBOM)¶
Each image carries a software bill of materials in SPDX format: the operating system packages, Tomcat, and the Java libraries in the Security Shepherd WAR. Each platform has its own.
# Print the SBOM of the amd64 image. Use "linux/arm64" for the ARM image,
# or --format '{{ json .SBOM }}' for both, keyed by platform.
docker buildx imagetools inspect "owasp/security-shepherd:$TAG" \
--format '{{ json (index .SBOM "linux/amd64").SPDX }}'
# Save it to a file to use with other tools
docker buildx imagetools inspect "owasp/security-shepherd:$TAG" \
--format '{{ json (index .SBOM "linux/amd64").SPDX }}' > "shepherd-$TAG.spdx.json"
# List the packages with Docker Scout, which reads the same SBOM, for your machine's platform.
# Needs you to be logged in to Docker Hub, with any account.
docker scout sbom --format list "owasp/security-shepherd:$TAG"
3. See how it was built¶
# BuildKit's provenance for the amd64 image: base image, Dockerfile, build arguments.
# Stored next to the image on Docker Hub but not signed, so it shows how the image says it
# was built. The check in step 1 is the one that proves it.
docker buildx imagetools inspect "owasp/security-shepherd:$TAG" \
--format '{{ json (index .Provenance "linux/amd64").SLSA }}'
4. Run exactly what you checked¶
A tag can move. A digest can't, so verify the digest and run the same one.
# The tag's digest. For a multi-platform image it's the image index, which covers every platform
# and is what's signed. A single platform's digest has no signed attestation of its own.
digest=$(docker buildx imagetools inspect "owasp/security-shepherd:$TAG" --format '{{ .Manifest.Digest }}')
# Verify it, then run it by digest
gh attestation verify "oci://docker.io/owasp/security-shepherd@$digest" \
--repo OWASP/SecurityShepherd \
--signer-workflow OWASP/SecurityShepherd/.github/workflows/release-build.yml \
--source-ref "$REF"
docker run --rm -p 8443:8443 "owasp/security-shepherd@$digest"
The image ships no TLS key: on its first start it generates its own self-signed certificate, so expect a browser warning at https://localhost:8443. For the full stack with its databases, see Getting started.