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.
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.
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.
ID: deployment-readiness.ci-cd-pipeline.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 latest as the primary tag.
Fail criteria: Build artifacts use latest tag 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 '"') .