Build artifacts tagged with commit SHA, git tag, or semantic version; Docker images use SHA not latest
Why it matters
Docker images tagged exclusively as latest make it impossible to pinpoint which code version is running in production, roll back to a known-good build, or audit what changed between deployments. SLSA Build-L2 requires traceable artifact provenance; SSDF DS.1 requires unique build identifiers. Without SHA or semantic version tagging, a failed deployment becomes a debugging exercise because latest is overwritten with each push — the previous good build is gone.
Severity rationale
High because mutable `latest` tags eliminate the ability to pin or roll back to a specific artifact, making incident recovery slower and deployment audits impossible.
Remediation
Tag Docker images with the commit SHA or semantic version in your CI/CD workflow. Never push latest as the only tag.
# .github/workflows/deploy.yml
- name: Build and push image
run: |
COMMIT_SHA=${{ github.sha }}
docker build -t myregistry/myapp:${COMMIT_SHA:0:7} .
docker push myregistry/myapp:${COMMIT_SHA:0:7}
For semver-based projects:
- run: |
VERSION=$(npm pkg get version | tr -d '"')
docker build -t myregistry/myapp:${VERSION} .
docker push myregistry/myapp:${VERSION}
Update your deployment manifests or Helm values to reference the specific tag, not latest. Store the mapping of version → commit in release notes or GitHub Releases.
Detection
-
ID:
artifact-versioning -
Severity:
high -
What to look for: Enumerate every relevant item. Check CI/CD pipeline configuration for artifact versioning strategy. For Docker images, look for Dockerfile and CI/CD workflow to see if images are tagged with SHA, semantic version, or tag rather than
latest. Check for package.json version field and whether builds use version numbers. -
Pass criteria: At least 1 of the following conditions is met. Build artifacts (Docker images, compiled packages, deployables) are tagged with commit SHA, git tag, or semantic version. Docker images are not tagged with
latestas the primary tag. -
Fail criteria: Build artifacts use
latesttag exclusively (in Docker), or no versioning scheme is evident in the build process. -
Do NOT pass when: The item exists only as a placeholder, stub, or TODO comment — partial implementation does not count as passing.
-
Skip (N/A) when: The project does not build artifacts or uses a platform that handles versioning automatically (e.g., Vercel auto-generates deployment IDs).
-
Cross-reference: For broader data handling practices, the Data Protection audit covers data lifecycle management.
-
Detail on fail:
"Docker images in Dockerfile are tagged only as 'latest'. No commit SHA or semantic version in build process."or"Build artifacts have no version identifier; CI/CD workflow does not tag deployments." -
Remediation: Add versioning to your build process. For Docker in GitHub Actions:
- name: Build and push Docker image run: | COMMIT_SHA=${{ github.sha }} docker build -t myregistry/myapp:${COMMIT_SHA:0:7} . docker push myregistry/myapp:${COMMIT_SHA:0:7}Or use semantic versioning:
- run: npm version patch # or minor, major - run: docker build -t myregistry/myapp:$(npm pkg get version | tr -d '"') .
External references
- iso-25010:2011 · reliability.maturity — Maturity — repeatable, versioned build and release process
- slsa:1.0 · Build-L2 — Versioned, reproducible build artifacts
- ssdf:800-218 · DS.1 — Store all forms of code based on the principle of least privilege
Taxons
History
- 2026-04-18·v1.0.0·Initial import from deployment-readiness·automated