If you pull Docker images from Docker Hub, third-party registries, or even your own registry, you’re trusting the entire chain from source code to your docker pull. The SolarWinds breach, the recent Docker CVE-2026-31431, and the Arch Linux AUR malware incident (June 2026, 1500+ affected packages) all make one thing clear: supply chain attacks target infrastructure you thought was safe.
In a homelab, you might think “I’m not a target.” You are — bots and automated scanners don’t discriminate. The good news: securing your container supply chain with open-source tools is straightforward and lightweight. This guide covers the three pillars — SBOM generation, vulnerability scanning, image signing, and verification — using Syft, Grype, Cosign, and Docker Content Trust.
Understanding the Container Supply Chain Security Landscape
Supply-chain levels for software artifacts (SLSA) defines a framework of security levels. For a homelab, achieving SLSA Level 2 is realistic: signed provenance, hosted builds, and verified sources. You don’t need a full enterprise platform to get there.
In June 2026, Docker launched Hardened Images with Aikido vulnerability scanning, and the industry continues pushing toward transparency. An SBOM (Software Bill of Materials) is the foundation — it tells you exactly what packages are inside every layer of your image. With an SBOM in hand, you can scan for known vulnerabilities, verify the image was built by a trusted source, and detect tampering between build and deployment.
The tools we’ll use fit into a single workflow:
Source → Build → SBOM (Syft) → Scan (Grype) → Sign (Cosign) → Deploy → Verify
Each step is optional and composable. Start with one, add the rest over time.
Generating SBOMs with Syft
Syft from Anchore generates SBOMs from container images and filesystems. It supports SPDX, CycloneDX, and Syft’s own JSON format.
Installing Syft
|
|
Or via Docker:
|
|
Generating SBOMs
Generate an SPDX SBOM for the image you use daily:
|
|
For CycloneDX format:
|
|
Comparing SBOMs Across Versions
Track how your images change over time:
|
|
Automating SBOM Generation
Use a systemd timer to generate SBOMs for your critical images weekly:
|
|
|
|
Scanning for Vulnerabilities with Grype
Grype pairs with Syft natively — you can feed it an SBOM or scan an image directly.
Installing Grype
|
|
Scanning Images
Basic scan with severity summary:
|
|
Show only vulnerabilities with a fix available:
|
|
Fail the scan if any high-severity vulnerabilities exist (useful for CI):
|
|
Pipeline: SBOM → Scan
Generate an SBOM and scan it in one chain:
|
|
Configuring Grype for Your Homelab
Create ~/.grype.yaml to exclude false positives:
|
|
Remediation Workflow
When Grype reports vulnerabilities:
- Check if it’s in the base image — update the base image tag
- If it’s in an added package — update the package version in your Dockerfile
- If no fix exists — consider a distroless or hardened base image
Signing Container Images with Cosign
Cosign from Sigstore is the de-facto tool for signing container images. It supports key-pair signing and keyless signing via OIDC.
Installing Cosign
|
|
Generating a Key Pair
|
|
This creates cosign.key (private) and cosign.pub (public). Store the private key securely — consider using a password manager or age encryption.
Signing an Image
Push your image to a registry, then sign:
|
|
Cosign stores the signature as an additional manifest in the same registry under the tag myregistry.local/myapp:sha256-<digest>.sig.
Verifying an Image
|
|
The output includes the signature payload with the image digest. If the image has been tampered with, verification fails.
Keyless Signing with OIDC
For CI pipelines on GitHub Actions or GitLab CI:
|
|
Cosign uses the OIDC token from the CI environment (no key management needed). Verification for keyless signatures uses the Fulcio root:
|
|
Integrating with Docker Buildx
Use build attestations for provenance:
|
|
Then sign the attestation:
|
|
Storing Public Keys
Commit cosign.pub to your infrastructure Git repo:
|
|
Then any team member can verify images from your registry.
Enforcing Signed Images with Docker Content Trust
Docker Content Trust (DCT) uses Notary under the hood to enforce that only signed images can be pulled or pushed.
Enable Docker Content Trust
|
|
With DCT enabled, every docker push, docker pull, and docker build will verify signatures.
Pushing Signed Images
|
|
Docker will prompt for the root key passphrase and the repository passphrase. Once configured, push succeeds only if the image is signed.
Adding Delegated Signers
For teams or multiple machines:
|
|
Then the signer can push signed images with their own key.
Inspecting Trust Data
|
|
Limitations in a Homelab
DCT works best with Docker Hub or a Notary-signer-enabled registry. For a simple Docker Registry v2, consider using Cosign exclusively, as DCT requires a Notary server alongside your registry.
Building a Practical Homelab Pipeline
Combine everything into a Gitea Actions workflow:
|
|
For day-to-day use, add these aliases to your .bashrc:
|
|
Run verification before deploying any image to production services in your homelab:
|
|
Conclusion
Container supply chain security isn’t just for enterprises. With Syft, Grype, and Cosign, you can generate SBOMs, scan for vulnerabilities, and sign your images — all with open-source tools and a few shell commands. Start with Syft and Grype (the biggest security gain with the least effort), then add Cosign when you want to guarantee image integrity.
The full workflow — SBOM → Scan → Sign → Verify — takes about 15 minutes to set up and protects every image you deploy.