Skip to main content
CleanStart

Knowledge Hub

CleanStart Image Verification Guide

Applies to: All CleanStart container images Tools: cleanimg CLI, Cosign, Crane Last updated: April 2026

Overview

Every CleanStart container image is cryptographically signed and ships with supply chain attestations. Before deploying an image, you should verify its signature, check SLSA provenance, and optionally pin the image by digest to ensure immutability.

This guide covers three verification workflows: signature verification, provenance and SBOM attestation checks, and digest pinning.

Prerequisites: Install cleanimg (v1.0.196+). Cosign and Crane are bundled or must be available in your PATH.

1. Signature Verification

CleanStart images are signed with Cosign. You can verify using a KMS key, a local public key, or Sigstore keyless mode.

Verify with KMS Key

cleanimg verify gcr.io/project/redis:8.2.2 \  --kms-key gcpkms://projects/my-project/locations/us-central1/keyRings/ring/cryptoKeys/key \  --output json

Verify with Local Public Key

cleanimg verify gcr.io/project/redis:8.2.2 \  --key /path/to/cosign.pub

Verify with Keyless (Sigstore)

Keyless verification uses Sigstore's Fulcio CA and Rekor transparency log. No key management required.

cleanimg verify gcr.io/project/redis:8.2.2 \  --keyless \  --issuer https://accounts.google.com \  --identity builder@my-project.iam.gserviceaccount.com

If --issuer and --identity are omitted, any valid Sigstore certificate is accepted.

Full Flag Reference

Flag

Description

<IMAGE>

Image reference to verify (positional, required)

--keyless

Use Sigstore keyless verification (Fulcio + Rekor)

--key <PATH>

Path to public key file for keyed verification

--kms-key <URI>

KMS key URI (gcpkms://... or awskms://...)

--verify-provenance

Also verify SLSA provenance attestation

--verify-sbom

Also verify SBOM attestation

--issuer <URL>

Expected OIDC issuer for keyless verification

--identity <ID>

Expected certificate identity for keyless verification

--output <FMT>

Output format: text (default), json, quiet

--auth-mode <MODE>

Registry auth: adc (default), workload-identity, anonymous

2. Provenance Verification

CleanStart images include SLSA Level 3+ provenance attestations that document exactly how the image was built, including the builder identity, source materials, and build parameters.

Verify Provenance

cleanimg verify gcr.io/project/redis:8.2.2 \  --kms-key gcpkms://projects/my-project/locations/us-central1/keyRings/ring/cryptoKeys/key \  --verify-provenance

Verify Provenance with Cosign Directly

cosign verify-attestation \  --type slsaprovenance \  --key gcpkms://projects/my-project/locations/us-central1/keyRings/ring/cryptoKeys/key \  gcr.io/project/redis:8.2.2

What Provenance Contains

The SLSA provenance attestation (predicate type https://slsa.dev/provenance/v0.2) records:

  • Builder ID -- The build system that produced the image
  • Build type -- The build pipeline used
  • Invocation -- Config source, parameters, and environment at build time
  • Materials -- Package dependencies with cryptographic digests
  • Metadata -- Timestamps, build ID, completeness, and reproducibility flags

3. SBOM Attestation Verification

CleanStart images can include an attached SBOM (Software Bill of Materials) attestation listing every package in the image.

Verify SBOM Attestation

cleanimg verify gcr.io/project/redis:8.2.2 \  --kms-key gcpkms://projects/my-project/locations/us-central1/keyRings/ring/cryptoKeys/key \  --verify-sbom

Verify Both Provenance and SBOM

cleanimg verify gcr.io/project/redis:8.2.2 \  --key /path/to/cosign.pub \  --verify-provenance \  --verify-sbom \  --output json

Extract the SBOM

To extract and inspect the SBOM content (rather than just verifying the attestation signature), use the SBOM scanner:

sbom gcr.io/project/redis:8.2.2 \  --format cyclonedx-json \  --output redis-sbom.json

See the SBOM Scanner documentation for full output format options, CI gate policies, and compliance checks.

4. Digest Pinning

Tags are mutable -- redis:8.2.2 can point to different content over time. Digest pinning locks your deployment to an exact image.

Resolve a Tag to Its Digest

cleanimg resolve-digest gcr.io/project/redis:8.2.2

Output:

sha256:a1b2c3d4e5f6... # SHA-pinned reference:gcr.io/project/redis@sha256:a1b2c3d4e5f6...

Verify an Image Matches an Expected Digest

cleanimg verify-digest \  --image gcr.io/project/redis:8.2.2 \  --expected sha256:a1b2c3d4e5f6...

Or read the expected digest from a file:

cleanimg verify-digest \  --image gcr.io/project/redis:8.2.2 \  --digest-file expected-digest.txt

Flag Reference: resolve-digest

Flag

Description

<IMAGE>

Image reference to resolve (positional, required)

Flag Reference: verify-digest

Flag

Description

--image <REF>

Image reference (required)

--expected <DIGEST>

Expected digest, e.g. sha256:abc123...

--digest-file <PATH>

Path to file containing expected digest

5. Registry Authentication

All verification commands support three authentication modes via the --auth-mode flag:

Mode

Description

Use Case

adc (default)

Google Application Default Credentials

GKE workloads, local dev with gcloud auth

workload-identity

GKE Workload Identity Federation

GKE pods with bound service accounts

anonymous

No authentication

Public registries

For private registries, ensure Docker credentials are configured:

# GCRgcloud auth configure-docker # Harbor or other registriescleanimg auth login registry.example.com --username user --password token

6. CI/CD Integration

GitHub Actions Example

- name: Verify image signature and provenance  run: |    cleanimg verify ${{ env.IMAGE_REF }} \      --kms-key gcpkms://projects/my-project/locations/us-central1/keyRings/ring/cryptoKeys/key \      --verify-provenance \      --verify-sbom \      --output quiet - name: Pin image digest  run: |    DIGEST=$(cleanimg resolve-digest ${{ env.IMAGE_REF }} | head -1)    echo "PINNED_IMAGE=${{ env.IMAGE_BASE }}@${DIGEST}" >> $GITHUB_ENV - name: Verify digest before deploy  run: |    cleanimg verify-digest \      --image ${{ env.IMAGE_REF }} \      --digest-file expected-digests/${{ env.IMAGE_NAME }}.sha256

Kubernetes Admission Policy

Use digest-pinned references in your deployments:

containers:  - name: redis    image: gcr.io/project/redis@sha256:a1b2c3d4e5f6...

Combine with a Kubernetes admission controller (e.g., Kyverno, OPA Gatekeeper) to enforce that all images must have valid signatures and provenance.

7. Troubleshooting

"no matching signatures" error -- The image may not be signed with the key you specified. Verify you are using the correct public key or KMS URI for the signing key that was used at build time.

"MANIFEST_UNKNOWN" error -- The image reference does not exist in the registry. Check the tag and registry URL.

Keyless verification fails -- Ensure --issuer and --identity match the values used during signing. Run without these flags first to see what identity signed the image.

Digest mismatch -- The image content has changed since the digest was recorded. This could indicate the tag was re-pushed. Investigate before deploying.

Auth failures -- Run cleanimg auth list to check configured registries. For GCR, ensure gcloud auth configure-docker has been run.