About The Project
Recently I’ve started supporting a package in the Arch User Repository (AUR) in order to contribute to the Arch Linux project. In an effort to “automate all the things!”, I have regular Jenkins builds cloning and building the upstream Github project. This blog post outlines how I’ve tried to aligned to the Supply Chain Level for Software Artifacts framework as an exercise in securing build supply chains for community contributions. The final Jenkins build architecture can be seen below.
Documenting The Build
Currently, I have a Jenkins job called “libtins-build” which as the name implies builds the libtins library. If you’re not familiar with libtins, it’s a high level network packet crafting library written in C++. This package was orphaned in the AUR, and I “adopted” it to maintain. The build itself is pretty simple and follows the build instructions within the README. They are as follows:
- clone repo from upstream github URL.
- mkdir build && cd build;
- cmake ../;
- make -j $(nproc);
make -j $(nproc); command will run make with as many cores as the underlying machine has. At this point, the artifact of the shared library is produced. Arch Linux’s PKGBUILD file format which describes how to build and install a software package perform similar steps but with macros to define installation and the particular directories to install the shared library to. After successfully building and testing the package, it’s ready to be shipped off to the AUR.
What is the AUR?
Being a long time user of Arch Linux, I wanted to contribute back in the form of maintaining user packages. This is where the Arch User Repository (AUR) comes into play. The AUR contains numerous independently managed packages and libraries for endusers to download. The AUR is often one of the compelling reasons some switches to the Arch Linux distribution; second only to saying “I use Arch BTW…” to all their friends. During the installation phase of a package , it’s possible to view the package build and independently validate what’s about to happen on your system. The images below show what occurs when trying to install (or upgrade) a package from the AUR via the “yay” package manager.
The SHA256SUM variable contains the SHA256 hash of the package specified by the “source” variable. If these hashes do not match, then the build will be aborted. Manually verifying the hashes of upstream repos against repos specified in the PKGBUILD is cumbersome, but possible. Suppose the upstream Github repo was compromised, and older releases were later backdoored or modified with illintent. The hash in the PKGBUILD would not match the new hash of the tarball, resulting in not being installed on the end users machine. While this level of protection exists, that’s not to say packages haven’t been maliciously tampered with in the past. Notably, in 2018 a bad actor adopted an orphaned package (one not maintained by anyone in the community) and made malicious modifications to steal information about the end user’s systems and poste them to Pastebin. Trusting upstream repos for dependencies and source code presents an interesting element in your threat model. What happens when you’re wrong? What does the damage look like? Usually the answer is “not good”, but how can I build trust with people looking to use libraries I’m publishing on the AUR? This is where SLSA comes in.
What is SLSA?
Supply chain Levels for Software Artifacts or “SLSA” seeks to provide developers with a framework to prevent against supply chain tampering with their software builds. SLSA is broken up into four separate levels of increasingly more strict requirements to achieve a higher level of security within their software supply chain. The requirements were created through industry collaboration across multiple sectors and is currently in “alpha”. In the next section we’ll explore some interesting gaps or questions that I was left with from the SLSA framework.
Working Towards Achieving SLSA Levels
Looking at level-1, the requirements of SLSA are as follows:
- “The build process must be fully scripted/automated and generate provenance. Provenance is metadata about how an artifact was built, including the build process, top-level source, and dependencies. Knowing the provenance allows software consumers to make risk-based security decisions. Provenance at SLSA 1 does not protect against tampering, but it offers a basic level of code source identification and can aid in vulnerability management.”
Looking at the diagram provided at the beginning of this blog post, it appears that documenting the build process and making it available to end-users has given Arch Cloud Labs the ability to say that SLSA level one was achieved. However, one critical piece remains is that there’s no verifiable way for the end user to believe that this pipeline exists short of exposing a Jenkins dashboard. One may argue that presenting the Jenkins dashboard externally may present a greater risk. That aside, let’s take a look at achieving a higher level of SLSA.
Diving into the level-2 requirements, SLSA requires:
- “Using version control and a hosted build service that generates authenticated provenance. These additional requirements give the software consumer greater confidence in the origin of the software. At this level, the provenance prevents tampering to the extent that the build service is trusted. SLSA 2 also provides an easy upgrade path to SLSA 3.”
The source code I’m building is under another individuals control on Github entirely. While this “checks the box” on using version control, given it’s not a repository I control, it feels like I don’t meet this SLSA level. Althought, this brings up interesting questions about 3rd party dependencies in other projects. At this point I have simply instrumented the build instructions through Jenkins, and provided the build log in the form of a Discord webhook. At best I’ve created a semi-automated mechanism for generating build artifacts and sharing them with the community.
While this might be helpful for some, it provides far too much vagueness to say that SLSA level-2 has been achieved. It does however improve my overall homelab build pipeline aligning to a more mature framework to have a better end product for the community.
Beyond The Blog
The SLSA framework provides an excellent opportunity for organizations to better understand “from farm-to-table” how their software is built. It also provides an opportunity for home lab enthusiasts to make interesting build pipelines while simulating “what would this look like if my homelab was production?”. An interesting ongoing effort within the Arch Linux packaging community is an effort to make ALL builds reproducable. This would provide endusers with easy validation that determenistic builds can be achieved. This is being discussed in an open issue on SLSA’s Github project.
Thank you for taking the time to read this, I hope you found it entertaining.