When Bitnami moved its long-trusted catalog behind a paid tier, thousands of teams woke up to a supply-chain problem they didn’t choose. The free images they had pinned in production would stop getting updates, and the migration clock started that morning. QuenchWorks is my answer to that: a from-scratch, security-first catalog of container images and Helm charts, built entirely from source, hardened under a strict zero-CVE build gate, signed, and free. This is how it’s put together and why each decision earns its place.
The problem
The Bitnami catalog was popular for good reasons. It was broad, it was versioned, and it was maintained well enough that most teams never thought about it. Its weaknesses only became obvious once access changed: you didn’t control the build, you couldn’t prove what was inside a given image, and continued free access was never actually guaranteed.
That last point is the one that bites. When an upstream catalog changes its terms, every image: line you pinned becomes a liability at once. You either pay, fork, or scramble. And even before that day comes, an opaque image is its own quiet risk. If you can’t see how a layer was produced, you can’t reason about what a scanner finds inside it, and you can’t answer a security review with anything better than “we trust the vendor.”
Most hardened-image alternatives fix one slice of this and charge for the rest. I wanted the whole thing: a catalog broad enough to actually replace Bitnami for common workloads, provable rather than “trust us,” and free with no pull limits and no lock-in. If it couldn’t be all three, it wasn’t worth building.
Constraints
A handful of hard limits shaped every later decision.
- Zero fixable CVEs, enforced by the build. Not a nightly report someone reads later. A gate that fails the build so a vulnerable image never ships in the first place.
- Built from source. No repackaging of someone else’s opaque binary layers. If it’s in the image, we produced it.
- Provable. Every image needs a bill of materials and build provenance that a consumer can verify without trusting me.
- Free to run and maintain. The whole system builds on free CI, so cost can never be the reason it slips behind a paywall later.
- Multi-arch. amd64 and arm64, because production is both now, not one or the other.
Those constraints pull against each other. Zero fixable CVEs across 150+ images sounds impossible if you picture a fat base image. Building everything from source sounds slow. The architecture is what makes them coexist.
Architecture
The catalog is a pipeline, not a pile of Dockerfiles. Each image is declared as an apko plus melange spec, built from source on Wolfi, scanned against a zero-fixable-CVE gate, signed, and only then published pinned by digest. Charts sit on a shared library chart and reference those images by digest.
The single decision that makes the zero-CVE gate realistic is the base. QuenchWorks builds on Wolfi, a glibc Linux undistro designed for containers. Most images start with no shell, no package manager, and a tiny set of packages. There’s simply very little in the image that can be vulnerable, so keeping the gate green is a fight you can actually win instead of an endless race against a bloated base.
The image itself is assembled declaratively. melange builds signed APK packages from source, and apko composes those packages plus the Wolfi base into an OCI image with no Dockerfile involved. Because the whole thing is declared, the contents are known, reproducible, and easy to record as a bill of materials.
Tip
The zero-CVE gate and the minimal base are the same decision viewed twice. You don’t reach zero fixable CVEs by patching harder. You reach it by shipping so little that there’s almost nothing to patch.
A catalog is never done, though, because CVEs are disclosed against packages long after an image ships. So the pipeline runs in reverse on a schedule. A nightly Trivy rescan checks every published image, and when a fix lands upstream the affected image rebuilds, re-enters the gate, gets re-signed, and republishes under a new digest. The catalog trends toward zero drift without anyone babysitting it.
Implementation
Each image is a pair of specs. melange describes how to build the package from source, and apko describes how to assemble the final image. Here’s the shape of both, trimmed for clarity.
package: name: my-app version: 1.2.3environment: contents: packages: - build-basepipeline: - uses: fetch with: uri: https://example.com/my-app-${{package.version}}.tar.gz expected-sha256: '...' - uses: autoconf/configure - uses: autoconf/make - uses: autoconf/make-installcontents: repositories: - https://packages.wolfi.dev/os packages: - my-app - ca-certificates-bundleaccounts: users: - username: nonroot uid: 65532 run-as: 65532archs: - x86_64 - aarch64entrypoint: command: /usr/bin/my-appThe gate is one Trivy call, and it’s deliberately strict about what counts. It only fails on CVEs that have a fix available, because a vulnerability with no upstream patch isn’t something a rebuild can clear. Everything fixable has to be at zero before the image is allowed out.
# Fail the build if any FIXABLE HIGH/CRITICAL vulnerability is presenttrivy image --ignore-unfixed --severity HIGH,CRITICAL \ --exit-code 1 ghcr.io/quenchworks/my-app:latestOnce an image passes, it gets signed and attested before it’s pushed for real. Signing is keyless with Cosign, so there’s no long-lived private key to leak, and the SBOM and SLSA provenance ride along as attestations.
-
Build from source.
melangeproduces signed APKs;apkoassembles the image with the Wolfi base, nonroot user, and read-only root filesystem defaults. -
Gate on zero fixable CVEs. Trivy runs in comprehensive mode. One fixable HIGH or CRITICAL fails the pipeline, so a vulnerable image never reaches the registry.
-
Sign and attest. Cosign signs the image keyless, then attaches an SPDX SBOM and a SLSA build-provenance attestation.
-
Publish pinned by digest. The image is pushed, and the Helm charts reference it by
sha256:digest, never by a movable tag. -
Rescan nightly. A scheduled Trivy run watches for new fixes and triggers the self-heal rebuild loop.
On the delivery side, charts are the second half of the story. Every chart builds on a shared quench-common library chart, so common concerns like security context, probes, and labels live in one place instead of being copy-pasted 120 times. Each chart pins its image by digest.
Pinning by digest instead of tag is what makes the catalog trustworthy in practice. A tag can be moved; a digest can’t. When a consumer pins a QuenchWorks chart, they get exactly the bytes that passed the gate.
image: repository: ghcr.io/quenchworks/postgresql # Pinned by digest, not tag. This is the exact image that passed the gate. digest: 'sha256:abc123...'The proof only matters if consumers can check it, so verification is a first-class step, not an afterthought. Anyone can verify an image’s signature and attestations before it runs, and an admission policy can enforce that in the cluster so unsigned or unverifiable images never schedule.
cosign verify \ --certificate-identity-regexp '^https://github.com/quenchworks/' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ ghcr.io/quenchworks/postgresql@sha256:abc123...Results
The catalog is real and in use, not a proof of concept.
- 150+ container images built from source on Wolfi, each gated to zero fixable CVEs.
- 120+ production Helm charts on the shared
quench-commonlibrary, every one pinned to its image by digest. - Every image cosign-signed with an SPDX SBOM and SLSA provenance, published under an ArtifactHub verified-publisher organization.
- Multi-arch (amd64 and arm64), nonroot, and read-only root filesystem by default.
- A nightly rescan and self-heal rebuild loop that keeps the catalog current as upstream ships fixes.
- Free and independent. No subscription, no registry pull limits, no lock-in.
The counts above are current catalog figures. Per-image build times and scan times vary by package, so I’d treat any single number there as indicative rather than a benchmark.
Lessons
The biggest lesson is that the base image choice decides everything downstream. Trying to reach zero CVEs on a fat base is a treadmill; starting from Wolfi’s minimal surface turns the gate into something you can keep green for months. If I’d started anywhere else, the self-heal loop would be firing constantly and the whole thing would feel like bailing water.
The second lesson is that provenance costs far less than it’s worth. Signing and generating SBOMs added very little build time, but they change the catalog’s whole posture. It stops being “trust me” and becomes “verify it yourself,” which is the entire point of replacing an opaque upstream. If I were doing it again, I’d wire verification into the consumer docs even earlier, because an unverified signed image is only half the value.
The one thing I’d watch more carefully next time is chart sprawl. The quench-common library chart paid for itself immediately, but library conventions need to be locked down early. Once a few charts drift from the shared patterns, every future change gets more expensive.
Frequently Asked Questions
It’s zero fixable CVEs, and it’s mostly a consequence of the base. Wolfi images ship with almost nothing beyond what the app needs, so there’s very little surface for a vulnerability to live in. The Trivy gate then fails any build with a fixable HIGH or CRITICAL, so a vulnerable image can’t ship. Vulnerabilities with no upstream fix are tracked but don’t block, because a rebuild can’t clear them.
A tag is a movable pointer; a digest is the content itself. If you pin :latest or even :1.2.3, the bytes behind that tag can change. Pinning sha256:... guarantees you get exactly the image that passed the gate and was signed. It’s the difference between “probably the right image” and “provably the right image.”
Use cosign verify with the QuenchWorks certificate identity and OIDC issuer, as shown above. That checks the keyless signature against the transparency log. You can also verify the SBOM and SLSA provenance attestations, and enforce all of it in-cluster with an admission policy so nothing unsigned ever schedules.
The nightly Trivy rescan catches it. If the CVE is fixable, the affected image rebuilds from source, goes back through the gate, gets re-signed, and republishes under a new digest. You pick up the fix by moving your pin to the new digest. Nobody has to notice the CVE manually for the loop to run.
It’s free, with no subscription and no registry pull limits. The catch, if you call it one, is that you verify and pin things yourself rather than outsourcing trust to a vendor relationship. That’s a feature for most teams: you get provenance you can audit instead of a support contract you have to believe.
Yes. The charts and images are independent. You can pull a single hardened image by digest, or install one chart, without buying into everything. The quench-common library chart is an implementation detail of the charts, not something you have to adopt in your own repos.
