buildwarden

Build Warden Proposal

When doing research on SBOMs and attempting to evaluate automatic generation of attestations, I realized how easily the attestations of the artifact — excluding the hash-manifest — can be incredibly hard to verify and so could be incomplete, incorrect, or tampered with. It also sets expectations around both good behavior and perpetual vigilance by the author/publisher of an OSS package and gets orders-of-magnitude more complex for any package that bundles/vendors other packages. Given the reliance that most build systems take advantage of having both source and/or artifact repositories being available (and usually over the public internet), your artifact can accidentally or purposely contain almost anything. But it struck me that these are potentially answerable questions as we do so today with network isolation and tracked interfaces, it is just not necessarily guaranteed by the code’s author but by the build executor ** who generates the artifacts.

Build Warden is a platform for build executors which combines the security of network-isolated build containers with an ephemeral HTTPS Man-in-the-middle which logs all requests and responses during the build process and yields a verifiable non-falsifiable* ledger meant to be used along-side any author-provided attestations. This creates a significantly more-exhaustive manifest of all possible software included within the created artifacts and allows build providers (e.g. CodeBuild, GitHub Actions, CI and CI providers) to be able to attest that the build of the artifact (identifiable by hash and size) was secure separately and independently from the source’s author.

*As close as ephemeral private 2022 SSL certificates can achieve

How does it work?

BuildWarden is an application which orchestrates and configures 2 components, a Relay and network-isolated build container, instantiating a new instance of both on every build. BuildWarden’s input is a ContainerFile that contains the starting necessary starting container reference followed with the necessary build instructions on subsequent lines and with output artifacts as POST requests to an internal endpoint with their artifact filename/path (e.g. https://artifact/<filename> though the idiomatic name may be a form-data parameter or otherwise decoupled from url semantics).

To run the build, BuildWarden creates a new Relay instance and a new ephemeral ContainerFile which injects the network configuration between the initial container reference and the build instructions. This installs the ephemeral public Certificate-Authority certificate generated by the Relay to the container’s root certificates and updates any necessary network configurations so DNS properly points to the Relay IP for all requests. It then runs the build through network-isolating the build container to only be able to contact the Relay endpoint.

The Relay is an SSL-terminating intentional Man-In-The-Middle proxy that generates an build-ephemeral Certificate Authorizing public/private certificate pair at startup. The private portion is never stored outside its process and is used to both generate site-specific ephemeral certificates for all HTTPS requests it receives as well as sign individual ledger entries. The Relay then forwards the request to its intended target or a secondary proxy and records both the requests and responses separately to the ledger, both for simplicity of the ledger’s timeline and allowing for build processes that do requests concurrently. Any POST requests to the specific artifact endpoint are simply not forwarded externally and are logged in the same way as any contents retrieved.

Each entry in the ledger is signed with the ephemeral certificate, where the first entry is the public certificate itself alongside an entry for the initial ContainerFile Warden starts the build with. All subsequent entries contain metadata including URL and content hashes, references to specific separate output files for headers and content, and their previous entry’s signature. The Relay is shut down when the build container shuts down, which removes any reference to the private certificate’s contents. This ensures that the ledger cannot be altered afterwards without cracking the ephemeral private certificate.

When the ledger is given an immutable reference and signed by a build executor to a persistent tamper-resistent ledger web service like SigStore, this can give software consumers an additional layer of transparency and closes potential gaps where author-supplied SBOM attestations may be incomplete, inaccurate, or intentionally tampered with. It also opens new possibilities around automatically generating, correcting, or identifying relationships that SBOMs may or may not attest to as a result.

FAQ

Wait, didn’t you start saying you wanted to generate SBOMs? Why does this not generate an SBOM?

So while the ledger’s contents combined with the artifact could potentially be used to generate an SBOM, it differs in the source of the attestations (the build executor), is notably more-exhaustive (leading to many ways it may lead to false-positives) and has different provability guarantees for all sides. This portion can also be developed separately in tandem and for more than one format of SBOM, but given both the different guarantees and attestations that can be made in the formats and the difference between “this is everything the build used” versus “this is what is in the artifact” and the false-positives/negatives that can occur, it is meant to be a separate data source.

Shouldn’t this be able to solve more problems? Like what about the ‘artifact hash catalog’ to help identify actual sources?

We want to prioritize this foundational piece’s simplicity to ensure the base system is both secure and performant. This doesn’t preclude many solutions being built upon the data it provides, but we also don’t want to deeply couple its success to exact strategies or data analysis/warehouses as there are many different ways both the verifiable ledger and the available redirection to another proxy can be used (i.e. redirects to a proxy that talks to an internal/CodeArtifact/Artifactory repository or which refuses/allows specific endpoints) and it is meant to help close a specific gap in data-gathering separate from analysis portions. While it may be expandable to also include other resources (e.g. file system mount), keeping its surface area small of both measurement and interaction interface means a lower likelihood of opening an unverifiable or unmeasured gap.

What about certificate pinning?

This is a space that gets more-complicated and I am open for ideas. I honestly don’t know enough about what makes certificate pinning an actually good idea. The reason the relay is not an HTTPS Proxy is due to proxy support being opt-in for respecting the proxy configuration and, as such, can be subject to bugs in individual build system implementations and lead to more issues when multiple build-systems are used together. At the network layer, it’s notably more uniform and standardized and allows for external/internal/mirror repository replacements without additional configuration for the build system itself.

What if I want to add test coverage or documentation generation as a part of the build process? Doesn’t that generate a lot more false-positives?

Because artifacts are themselves POST requests, each can be considered to have a valid artifact-specific ledger within the full ledger, consisting of all entries up through the completion of the last request started before the artifact’s completion record. This is to protect against a streaming data source not being a properly tracked as a potential input. This means that if all of your build steps finish and the artifacts are posted, any requests occurring afterwards in the ledger can either be ignored or even truncated off the ledger without compromising the security of the ledger for earlier artifacts.

While you may not care about having a ledger for your coverage or documentation artifacts, it can be useful towards troubleshooting differences between local and build-executor-driven builds

How does this relate to In-Toto?

Admittedly, the project started before in-toto was known about. That said, they fundamentally differ on their intention. In-Toto puts an additonal burden on OSS authors to put together detailed metadata verifying that the stages during the production of an artifact come from the actors the author expects. As such, while it gives much greater detail and data on what the author intended their build process to be and the resources they intend to use, it does so at the cost of the author’s attention to details