
In July 2026, the news hit the DevOps world like a freight train: an intrusion at Hugging Face, one of the most trusted names in AI infrastructure, became the most-discussed reliability story of the month on Hacker News. Days later, researchers disclosed the ChainDrop npm campaign and a compromise of the keyv package — a dependency with over 127 million weekly downloads. None of these were Hollywood-style attacks on fortified enterprise fortresses. They were supply chain attacks, and they succeeded because somewhere in the chain, a small team trusted the wrong artifact.
Here is the uncomfortable truth for SMBs: you are the primary target. Attackers know large enterprises have SBOM mandates, signing pipelines, and dedicated AppSec teams. Your two-person DevOps team? It probably builds containers, pushes them to a registry, and deploys without ever asking who signed this image or what is actually inside it.
This guide gives you a pragmatic, open-source supply chain security program: generate SBOMs with syft, scan them with grype, sign images with Sigstore, and enforce verification in CI and at runtime. No enterprise budget required.
Why 2026’s Attacks Should Scare Every SMB
Modern attacks rarely target your servers directly anymore. Instead, they target the software you build on top of. The typical chain looks like this:
- An attacker compromises a popular open-source package or a maintainer’s account.
- A malicious version is published and pulled by thousands of builds — including yours.
- The poisoned code steals credentials, injects backdoors, or ships in your container image to production.
- Your customers, your data, and your reputation are the casualties — but the “breach” happened upstream, in a repo you never audited.
Worse: in containerized stacks, the risk compounds. A base image pulled from a public registry can contain vulnerable system libraries, and a single compromised build tool in your pipeline can sign its own malicious output. If you cannot answer “what is in this image, who built it, and can I prove neither was tampered with?” — you are running on trust, not security.
This is exactly the gap our DevSecOps for SMBs guide starts to close with scanning and shift-left checks. What follows is the next layer: artifact integrity.
Step 1: Generate an SBOM for Every Artifact
An SBOM (Software Bill of Materials) is exactly what it sounds like: a machine-readable inventory of every component in your software — libraries, system packages, language runtimes, and their versions. The two dominant formats are SPDX and CycloneDX. You cannot secure what you cannot see, and you cannot scan what you cannot enumerate.
Syft is the de facto open-source tool for this. Generate an SBOM for a container image or a source tree in one command:
# SBOM for a container image (CycloneDX JSON)
syft packages yourregistry/yourorg/app:v1.2.3 -o cyclonedx-json > sbom.json
# SBOM for a local codebase (SPDX JSON)
syft packages ./src -o spdx-json > sbom.spdx.json
# Quick human-readable inventory
syft packages yourregistry/yourorg/app:v1.2.3 -o table
Then scan that SBOM for known vulnerabilities with Grype:
grype sbom.json -o table
# Fail the build on high-severity findings
grype sbom.json --fail-on high -o table
Two habits make this stick:
- Generate the SBOM at build time, in CI, from the exact artifacts you publish — not from a snapshot taken later.
- Attach the SBOM to the image in your registry using OCI artifacts, so anyone (or any policy engine) can pull it later:
cosign attach sbom --sbom sbom.json yourregistry/yourorg/app:v1.2.3
Step 2: Sign Your Images with Sigstore — No Keys to Lose
Scanning tells you what is in the image. Signing tells you who built it and that it hasn’t been tampered with since. Traditional signing required managing private keys — and a leaked key is worse than no key at all. Sigstore fixes this with keyless signing: your CI system’s OpenID Connect (OIDC) identity (e.g., from GitHub Actions) becomes the signing credential, and the certificate is short-lived and automatically audited to a public transparency log.
With Cosign (v2+, where keyless is the default), signing a container image is one command:
# Keyless signing — CI identity becomes the certificate
cosign sign ghcr.io/yourorg/app:v1.2.3
# Classic key pair (still useful for air-gapped registries)
cosign generate-key-pair
cosign sign --key cosign.key ghcr.io/yourorg/app:v1.2.3
In a GitHub Actions workflow, the full SBOM + scan + sign sequence fits in a few steps:
jobs:
build-and-sign:
runs-on: ubuntu-latest
permissions:
id-token: write # required for keyless signing
contents: read
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t ghcr.io/${{ github.repository }}:${{ github.sha }} .
- name: Generate SBOM
run: syft packages ghcr.io/${{ github.repository }}:${{ github.sha }} -o cyclonedx-json > sbom.json
- name: Scan SBOM
run: grype sbom.json --fail-on high -o table
- name: Push image
run: docker push ghcr.io/${{ github.repository }}:${{ github.sha }}
- name: Sign image
run: cosign sign --yes ghcr.io/${{ github.repository }}:${{ github.sha }}
Anyone can now verify the artifact came from your workflow — not from a compromised laptop or a rogue maintainer’s account:
cosign verify ghcr.io/yourorg/app:v1.2.3 \
--certificate-identity-regexp "https://github.com/yourorg/*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
Step 3: Enforce Verification in CI and at Runtime
Signing only helps if you verify — automatically, every time. Two enforcement points matter:
In the pipeline: verify before deploy
# CI gate: the image must be signed by your workflow AND pass scanning
cosign verify --certificate-identity-regexp "https://github.com/yourorg/*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
ghcr.io/yourorg/app:v1.2.3
grype ghcr.io/yourorg/app:v1.2.3 --fail-on high -o table
In the cluster: reject unsigned images at admission
Your Kubernetes cluster should refuse to run images that don’t meet your policy. An admission controller like Kyverno (the same approach we use in our Policy as Code with OPA guide) makes this a declarative policy:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-signed-images
spec:
validationFailureAction: Enforce
rules:
- name: verify-signature
match:
any:
- resources:
kinds: ["Pod"]
verifyImages:
- image: "ghcr.io/yourorg/*"
key: |
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
-----END PUBLIC KEY-----
Combine this with strict secrets management so build credentials can’t be exfiltrated, and you have closed the loop: only verified, scanned, signed artifacts from your own pipelines can reach production.
The Minimum Viable Program: A 6-Item Checklist
- Generate an SBOM for every image and release artifact (syft).
- Scan every SBOM in CI and fail on high severity (grype).
- Sign every release with Sigstore keyless signing (cosign).
- Verify signatures as a deploy gate in CI.
- Enforce image verification in the cluster with Kyverno.
- Pin base images by digest and pin dependencies with lockfiles, so “latest” can never surprise you.
You can implement all six items this quarter with free, open-source tools. The hardest part isn’t the tooling — it’s making the decision to stop trusting and start verifying.
If you’d like a second pair of eyes on your build and deployment pipeline — or help rolling out SBOMs, signing, and admission policies across your stack — book a free consultation with our team and we’ll map out exactly what your SMB needs.