# Attestable builds: compiling verifiable binaries on untrusted systems using trusted execution environments
**Authors**: Daniel Hugenroth, Mario Lins, René Mayrhofer, Alastair R. Beresford
> 0000-0003-3413-1722 University of Cambridge Cambridge United Kingdom
> 0000-0003-1713-3347 Johannes Kepler University Linz Austria
> 0000-0003-1566-4646 Johannes Kepler University Linz Austria
> 0000-0003-0818-6535 University of Cambridge Cambridge United Kingdom
## Abstract
In this paper we present attestable builds, a new paradigm to provide strong source-to-binary correspondence in software artifacts. We tackle the challenge of opaque build pipelines that disconnect the trust between source code, which can be understood and audited, and the final binary artifact, which is difficult to inspect. Our system uses modern trusted execution environments (TEEs) and sandboxed build containers to provide strong guarantees that a given artifact was correctly built from a specific source code snapshot. As such it complements existing approaches like reproducible builds which typically require time-intensive modifications to existing build configurations and dependencies, and require independent parties to continuously build and verify artifacts. In comparison, an attestable build requires only minimal changes to an existing project, and offers nearly instantaneous verification of the correspondence between a given binary and the source code and build pipeline used to construct it. We evaluate it by building open-source software libraries—focusing on projects which are important to the trust chain and those which have proven difficult to be built deterministically. Overall, the overhead (42 seconds start-up latency and 14% increase in build duration) is small in comparison to the overall build time. Importantly, our prototype builds even complex projects such as LLVM Clang without requiring any modifications to their source code and build scripts. Finally, we formally model and verify the attestable build design to demonstrate its security against well-resourced adversaries.
copyright: none conference: ; isbn: ;
## 1. Introduction
Executable binaries are digital black boxes. Once compiled, it is hard to reason about their behavior and whether they are trustworthy. On the other hand, source code is easier to inspect. However, few have the ability, resources, and patience to compile all their software from scratch. Therefore, we want to allow recipients to verify that an artifact has been truthfully built from a given source code snapshot. This challenge has been popularized in the now-famous Turing Lecture by Ken Thompson on “Trusting Trust” (Thompson, 1984).
The problem of trusting build artifacts also presents itself in commercial settings where source code is typically not shared. Here as well the source code is the only source-of-truth that is inspectable by the employed engineers and auditors. During code review it is code changes and not binary output that is examined and, likewise, audit reports generally reference repository commits and not the hash of the shipped artifact. Hence, companies are interested in verifiable source-to-binary correspondence in an enterprise setting too. Where this correspondence cannot be verified, defects are difficult to identify—allowing them to spread down the supply chain to many targets.
There have been recent attacks which successfully targeted the build process. During the 2020 SolarWinds hack, attackers compromised the company’s build server to inject additional code into updates for network management system software (Zetter, 2023). As there were no changes to the source code repository, only forensic inspection of the build machines eventually unveiled the malicious change. In the meantime, the software was distributed to many customers in industry and government that relied on it to secure access to their internal networks. The US Cybersecurity & Infrastructure Security Agency (CISA) issued an emergency directive requesting immediate disconnect of all potentially affected products (Cybersecurity & Infrastructure Security Agency, 2021).
In 2024 a complex supply chain attack (CVE-2024-3094) against the XZ Utils package was uncovered that allowed adversaries to compromise vulnerable servers running OpenSSH (Lins et al., 2024). A key aspect that made this attack possible is that, for (open-source) projects utilizing Autoconf, it is a common practice that maintainers manually create certain build assets (e.g., a configure script), add it to a tarball, and then provide it to the packager, who builds the final artifact. In case of XZ, this tarball contained a malicious asset covertly included by the adversary that was not part of the repository. Here both the maintainer and the packager have opportunity to meddle with the final binary artifact.
Reproducible Builds (R-Bs, § 2.2) are the typically proposed solution to address potential discrepancies between source code and compiled binaries. Correctly implemented, R-Bs ensure source-to-binary correspondence by making the build process perfectly deterministic. Thus, they guarantee that the same source code always results in a bit-to-bit identical binary artifact output. This enables independent parties to reproduce binary artifacts, thus verifying that a given source input generated a given output. There are many successful projects that implement R-Bs (Project, 2024; Perry and Project, 2024; Project, 2024).
However, R-Bs come with their own challenges: They require substantial changes to the build process, which is time-intensive and therefore costly—not just as a one-time cost, but also as a continuing maintenance burden. Further, for closed-source software, the downstream consumer cannot check if their supplier has correctly applied R-B principles, since they are typically not given access to the required source code. Additionally, even for source-available software, the build process and compiler are often not available, for example due to intellectual property or licensing concerns. In reality, R-Bs only provide effective security benefits when there are independent builders who are continuously verifying that distributed artifacts are identical to their locally built ones.
We propose Attestable Builds (A-Bs) as a practical and scalable alternative where R-Bs are infeasible or costly to implement—including as a complement to extend R-B guarantees to consumers who cannot verify R-Bs themselves even if the primary build chain has R-B properties. For this we leverage Trusted Execution Environments (TEEs) to ensure that the build process is performed correctly and is verifiable. Unlike previous generations of TEEs (e.g., Intel SGX, Arm TrustZone), modern TEE implementations (e.g., AMD SEV-SNP, Intel TDX, AWS Nitro Enclaves) support full virtual machines with strong protection against interference by the hypervisor and physical attacks. Whereas this technology is typically used to achieve data confidentiality, in this work we leverage its integrity properties.
In our approach, the build process can be performed by an untrusted build service running at an untrusted cloud service provider (CSP), as long as the TEE hardware is trusted. We start by booting an open source machine image embedded inside a modern TEE. The embedded machine downloads the source code repository and commits to a hash of the downloaded files, including build instructions, in a secure manner before executing the build process inside a sandbox. Afterwards, the TEE hardware trust anchor attests to the booted image, the committed hash value, and the built artifact. This attestation certificate is shared alongside the artifact and is recorded in a transparency log. Recipients of the artifact can check the certificate locally and query the transparency log to verify that a given artifact has been built from a particular source code snapshot.
The paradigms of A-B and R-B can be composed to achieve stronger trust models that do not require trusting a single Confidential Computing vendor (see § 3.4). Table 1 highlights the similarities and differences between R-Bs and A-Bs. We believe that A-Bs would have prevented or substantially mitigated the feasibility of the mentioned SolarWind and XZ Utils attacks (see § 7.1).
In this paper, we make the following contributions:
- We present a new paradigm called Attestable Builds (A-Bs) that provides strong source-to-binary correspondence with transparency and accountability.
- We discuss short-comings of alternative approaches and devise a design relying on a sandbox and an integrity-protected observer.
- We implement an open-source prototype to demonstrate the practicality of A-Bs by building real-world software including complex projects like Clang and the Linux Kernel as well as packages that are hard to build reproducibly.
- We evaluate the performance of our system and find that it adds a (mitigable) 42 second start-up cost, which is small compared to typical build durations. It also imposes a performance overhead of around 14% in our default configuration and up-to 68% when using hardened sandboxes.
- We formally verify the system using Tamarin and discuss the underlying trust assumptions required.
Table 1. Comparison of Reproducible Builds (R-Bs) and Attestable Builds (A-Bs).
| Reproducible Builds | Attestable Builds |
| --- | --- |
| + Strong source-to-binary correspondence | |
| - High engineering effort for both initial setup and ongoing build maintenance | + Only small changes to the build environment needed [4pt] + Cloud service compatible |
| - Dependencies and tool chain need to be deterministic | Dependencies and tool chain can be R-B or A-B |
| - Environment might leak into build process undetected | + Enforces hermetic builds |
| + Machine independent | - Requires modern CPU |
| Requires trusting at least one party and their machine | Requires trusting the hardware vendor |
| - Requires open source | + Supports closed source and signed intermediate artifacts |
| + Can be composed to an anytrust setup (§ 3.4) | |
## 2. Background
Attestable builds integrates with modern software engineering and CI/CD patterns (§ 2.1) and provides an alternative to reproducible builds (§ 2.2). For this we leverage Confidential Computing technology (§ 2.3) and verifiable logs (§ 2.4). This section introduces the required background and building blocks.
### 2.1. Modern software engineering & CI/CD
Modern Software Engineering (SWE) involves large teams that requires efficient mediation of their collaboration aspects through software. Many projects rely on source control management (SCM) software like Git (project, 2024a) and Mercurial (community, 2024). The underlying repositories are often hosted by online services, such as GitHub (Inc., 2024c) or Bitbucket (Ltd, 2024). We call these Repository Hosting Providers (RHPs).
With increasing complexity, Continuous Integration (CI), has become an important component in modern software projects. Every published code change triggers a new execution of the project’s CI pipeline that builds, tests, and verifies the new code snapshot. In addition, some code changes might trigger a (separate) Continuous Deployment (CD) pipeline which after passing all checks distributes binaries automatically and re-deploys them to the production system. Such CI/CD pipelines are described in configuration files within the source code repository and then executed by online services, build service providers (BSPs), such as Jenkins (project, 2024a) or GitHub Actions (Inc., 2024b). The latter is an example where the RHP is also a BSP. Our prototype uses GitHub Actions to demonstrate how A-Bs can integrate into existing infrastructure.
Both RHPs and BSPs often do not manage their own machines, but use cloud infrastructure provided by cloud service providers (CSPs) such as Amazon Web Services (AWS), Microsoft Azure, or Google Cloud Platform (GCP). Although there are self-hosted alternatives, such as GitLab (Inc., 2024d), even those are often deployed via a CSP. We illustrate the involved parties in Figure 1.
<details>
<summary>x1.png Details</summary>

### Visual Description
## Diagram: Software Development and Deployment Pipeline
### Overview
The image is a black-and-white schematic diagram illustrating a linear workflow or pipeline for software development and deployment. It depicts the flow from developers to a final artifact, with distinct stages and components, likely representing a cloud-based development environment.
### Components/Axes
The diagram is organized into three main horizontal stages at the top, labeled with acronyms, and a foundational layer at the bottom.
**Top Row (Left to Right):**
1. **Label:** `DEVs`
* **Icon:** A group of three human silhouettes (representing developers).
* **Associated Element:** Two laptop icons stacked vertically, connected by a vertical line. An arrow originates from this point and points to the next stage.
2. **Label:** `RHP`
* **Icon:** A cylinder (database symbol) with a cloud icon overlapping its bottom-right quadrant.
* **Sub-label:** `Repository` (positioned directly below the cylinder/cloud icon).
* **Flow:** An arrow points from this stage to the next.
3. **Label:** `BSP`
* **Icon:** A gear (settings/process symbol) with a cloud icon overlapping its bottom-left quadrant.
* **Sub-label:** `CI/CD` (positioned directly below the gear/cloud icon).
* **Flow:** An arrow points from this stage to the final component.
**Final Component (Right):**
* **Icon:** A 3D cube.
* **Label:** `Artifact` (positioned directly below the cube).
**Bottom Layer:**
* A dashed horizontal line spans the width of the diagram, separating the top workflow from the bottom element.
* **Icon:** A cloud icon.
* **Label:** `CSP` (positioned to the right of the cloud icon).
### Detailed Analysis
The diagram presents a clear, sequential process flow:
1. **Initiation (DEVs):** The process begins with developers (`DEVs`) working on laptops. This represents the coding and development phase.
2. **Source Control (RHP / Repository):** The work from the developers is committed to a `Repository`. The cylinder icon is a standard symbol for a database or version control system (like Git). The overlapping cloud icon strongly suggests this repository is hosted in the cloud.
3. **Build & Deployment (BSP / CI/CD):** The code from the repository enters a `CI/CD` (Continuous Integration/Continuous Deployment) pipeline. The gear icon symbolizes automated processing, building, testing, and deployment. The overlapping cloud icon indicates this pipeline is also a cloud-based service.
4. **Output (Artifact):** The final output of the CI/CD process is an `Artifact`. The cube icon is a common representation for a deployable software package, container image, or library.
5. **Infrastructure Foundation (CSP):** The entire workflow above the dashed line is underpinned by the `CSP`. The cloud icon and acronym (commonly standing for Cloud Service Provider) indicate that the Repository, CI/CD pipeline, and likely the development environment itself are hosted on and managed by a cloud platform (e.g., AWS, Azure, Google Cloud).
### Key Observations
* **Linear Flow:** The process is strictly linear, with no feedback loops or decision points shown, suggesting a simplified, high-level view.
* **Cloud-Centric Design:** The consistent use of cloud icons overlapping the Repository and CI/CD components, plus the foundational CSP layer, emphasizes that this is a cloud-native or cloud-first development workflow.
* **Acronym Usage:** The primary stage labels (`DEVs`, `RHP`, `BSP`, `CSP`) are acronyms. Their exact meaning is not defined in the image, but common interpretations in this context could be:
* `RHP`: Possibly "Repository Hosting Platform" or similar.
* `BSP`: Possibly "Build Service Platform" or "Build & Ship Pipeline."
* `CSP`: Almost certainly "Cloud Service Provider."
* **Abstraction:** The diagram abstracts away specific tools (e.g., GitHub, Jenkins, Docker) in favor of generic symbols and categories.
### Interpretation
This diagram illustrates a modern, cloud-based software delivery lifecycle. It demonstrates the separation of concerns and the handoff points between different phases of development:
* **Human to System Handoff:** The `DEVs` represent the human creative input, which is then handed off to automated systems (`Repository`, `CI/CD`).
* **Automation Chain:** The core of the process is an automated chain where code committed to a repository automatically triggers build, test, and deployment processes, culminating in a versioned artifact.
* **Infrastructure as a Foundation:** The placement of `CSP` at the bottom, separated by a dashed line, is significant. It visually communicates that the Cloud Service Provider is the foundational platform upon which all the development, repository, and CI/CD tooling is built and operated. This implies managed services, scalability, and reduced operational overhead for the development team.
* **Purpose:** The diagram is likely used to explain a company's development infrastructure, onboard new engineers, or document a system architecture. It emphasizes efficiency, automation, and cloud adoption as key principles of their engineering practice. The lack of specific tool names makes it a conceptual model applicable to various technology stacks that follow this pattern.
</details>
Figure 1. Developers (DEVs) commit to a source code repository at a repository hosting provider (RHP). Changes trigger the CI/CD pipeline at a build service provider (BSP) and generate new binary artifacts. RHP and BSP typically run on servers provided by a cloud service provider (CSP).
### 2.2. Reproducible builds (R-Bs)
The use of CI/CD brings many benefits to developers: automated checks ensure that no “broken code” is checked in, builds are easily repeatable since they are fully described in versioned configuration files; and long compile/deploy cycles happen asynchronously. However, they also shift a lot of trust to the RHP, BSP, and CSP. These online services are opaque and any of them can interfere with the build process. Therefore, the conveniently outsourced CI/CD pipeline undermines the trustworthiness of the generated artifacts. This leads to a particularly tricky situation, as its binary output is hard to inspect and understand. Therefore, trust in the process itself is just as important as trust in its input.
R-Bs have been proposed as a solution to ensure source-to-binary correspondence. The underlying approach is to make the build process fully deterministic such that the same source input always yields perfectly identical binary output. In a project with R-Bs malicious build servers can be uncovered by repeating the build process on a different machine. Correctly set up, the builds are replicated by independent parties that then compare their results.
However, introducing R-Bs to a software project is challenging (Fourné et al., 2023; Shi et al., 2021; Butler et al., 2023). For bit-to-bit identical outputs, the build process needs to be fully described in the committed files and all steps need to be fully deterministic. However, sources of non-determinism are plentiful as outputs can be affected by timestamps, archive metadata, unspecified filesystem order, build location paths, and uninitialized memory (Fourné et al., 2023; Shi et al., 2021).
While many sources of non-determinism can be eliminated with effort and tooling, other steps, such as digital signatures used to sign intermediate artifacts in multi-layered images, cannot easily be made deterministic. This is because typical signature algorithms break when random/nonce parameters become predictable and might leak private key material as a result (Katz and Lindell, 2007). For example, consider a build process for a smartphone firmware image that builds a signed boot loader during its process. This inner signature will affect the following build artifacts and is not easily hoisted to a later stage. In other instances, this signing process might happen by an external service or in a hardware security module (HSM) to protect the private key and therefore can never be deterministic.
Critically, for the downstream package to be reproducible, all its dependencies need to be reproducible as well. This also applies for dependencies that are shipped as source code, as R-B is a property of the build system. Facing non-determinism in any of the (transitive) upstream dependencies, a developer either needs to fix the upstream dependency or fork the respective sub-tree. In practice, the verification of having achieved R-B is often done heuristically and newly identified sources of non-determinism can cause a project to loose its status (Fourné et al., 2023). Despite the challenges, there are large real-world projects that have successfully adopted R-Bs. Examples are Debian (Project, 2024), NetBSD (Inc., 2024e), Chromium (Project, 2024), and Tor (Perry and Project, 2024). However, these came at considerable expenses in terms of required upgrades to the build system and on-going maintenance costs (Lamb and Zacchiroli, 2021; Fourné et al., 2023).
The Debian R-B project stands out due to its scale and highlights the challenges of R-Bs, taking twelve years to produce the first fully reproducible Debian image (Gevers, 2023; LWN.net, 2025). A typical challenge is to motivate upstream developers to provide reproducible packages. This even lead to the introduction of a bounty system (Gevers, 2023). The project’s dashboard (et al., 2025) shows that the number of unreproducible packages dropped from 6.1% (Stretch, released 2017) to 2.0% (Bookworm, released 2023). This suggests that the remaining packages are particularly difficult to convert to R-Bs. Therefore, we picked some of these packages for our practical evaluation (§ 4.1).
### 2.3. Confidential Computing
Executing code in a trustworthy manner on untrusted machines is a long standing challenge. Enterprises face this challenge when processing sensitive data in the cloud and financial institutions need to establish trust in installed banking apps. These scenarios require a solution that ensures that the data is not only protected while in-transit or at-rest, but also when in-use. Trusted Execution Environments (TEEs) allow the execution of code inside an enclave, a specially privileged mode such that execution and memory are shielded from the operating system and hypervisor. Typically, the allocated memory is encrypted with a non-extractable key such that it resists even a physical attack with probes used to intercept communication between CPU and RAM (and potentially interfere with). Even the hypervisor can only communicate with the enclaves via dedicated channels, e.g., vsock or shared memory, although the hypervisor maintains the ability to pause or stop code execution inside an enclave.
Earlier technologies such as ARM TrustZone (Pinto and Santos, 2019) and Intel SGX (Costan, 2016) create enclaves on a process level. This requires application developers to rewrite parts of their application using special SDKs so secure functionalities are run inside an enclave. In particular, Intel SGX has proven to be vulnerable to side-channel attacks that allow adversaries to extract secret information from enclaves (Chen et al., 2019; Skarlatos et al., 2019; Murdock et al., 2020; Van Schaik et al., 2020). It also imposes further practical limitations, such as a maximum enclave memory size and performance overhead.
More recent technologies such as Intel TDX (Corporation, 2024) and AMD SEV-SNP (Inc., 2024a) boot entire virtual machines (VMs) in a confidential context. This promises to simplify the development of new use-cases as existing applications and libraries can be used with little to no modification. In addition, VMs can be pinned to specified CPU cores, reducing the risk of timing and cache side-channel attacks. AWS Nitro is a similar technology, built on the proprietary AWS Nitro hypervisor and dedicated hardware. The trust model is slightly weaker as the trusted components sit outside the main processor. We choose AWS Nitro for our prototype due to its accessible tooling, but it can be substituted with equivalent technologies.
It is important for the critical software to verify that it is running inside a secure enclave. Likewise, users and other services interacting with critical software need to verify the software is running securely and is protected from outside interference and inspection. This is typically achieved using remote attestation. On a high-level, the curious client presents a challenge to the software that claims to run inside an enclave. The software then forwards this challenge to the TEE and its backing hardware who signs the challenge and binds it to the enclave’s Platform Configuration Registers (PCRs). The PCRs are digests of hash-chained measurements that cover the boot process and system configuration that claims to have been started inside the TEE (Simpson et al., 2019).
It is typically not possible to run an enclave inside another enclave or to compose these in a hierarchical manner—although new designs are being discussed (Castes et al., 2023). This presents a challenge in our case as we need to run untrusted code, i.e. the build scripts stored in the repository, inside the enclave. We work around this technical limitation by sandboxing those processes inside the TEE.
### 2.4. Verifiable logs
A verifiable log (Eijdenberg et al., 2015) incorporates an append-only data structure which prevents retroactive insertions, modifications, and deletions of its records. In summary, it is based on a binary Merkle tree and provides two cryptographic proofs required for verification. The inclusion proof allows verification of the existence of a particular leaf in the Merkle tree, while the consistency proof secures the append-only property of the tree and can be used to detect whether an attacker has retroactively modified an already logged entry. While such a transparency log is not strictly necessary to verify the attested certificate of an artifact, it adds additional benefits such as ensuring the distribution of revocation notices, e.g., after discovering vulnerabilities or leaked secrets. Artifacts providers can also monitor it to detect when modified versions are shared or their signing key is being used unexpectedly. A central log can also be used to include additional information, such as linking a security audit to a given source code commit (§ 7).
## 3. Attestable Builds (A-Bs)
This section introduces the involved stakeholders, the considered threat model, the design of a typical A-B architecture, and how it can be composed with R-Bs.
### 3.1. Stakeholders
The verifier receives an artifact, e.g., an executable, either directly from a specific BSP or via third-party channels. This could be a user downloading software or a developer receiving a pre-built dependency from a package repository. In general, the verifier does not trust the CI/CD pipeline and therefore wants to verify the authenticity of the respective artifact. The artifact author, e.g., a developer or a company, regularly builds artifacts for their project and distributes them to downstream participants. Thus, the system should integrate with existing version control systems hosted by an RHP. The artifact author also does not trust the CI/CD pipeline, as they do not control the involved hardware. Therefore, they need to detect any unauthorized manipulation. All other stakeholders (RHP, BSP, CSP, HSP, …) are untrusted. We assume there are no restrictions on combining multiple roles on one stakeholder, which is the realistic and more difficult set-up as it makes interference less likely to be detected. For example, a self-hosted Gitlab operator would take over the role as RHP to manage the source code using git, the BSP by providing build workflows, and the CSP by providing the underlying servers that execute the build steps. Only for the transparency log requiress a threshold of honest operators, e.g., in the form of independent witnesses tracking the consistency of the log similar as it is already done in established infrastructure such as Certificate Transparency (Laurie, 2014) and SigStore (Newman et al., 2022).
### 3.2. Threat Model
The main security objective is to provide an attested build process with strong source-to-binary correspondence guarantees. We do not consider confidentiality or availability as security objectives in A-Bs, assuming that the source code is not inherently confidential and that ensuring availability of relevant components in the build pipeline is the responsibility of the infrastructure provider. However, since the TEEs can also provide confidentiality, A-Bs can be adapted accordingly. Our threat model focuses on the build process as illustrated in Figure 1, describing pipelines where an artifact author publishes code to a repository, which is then built and deployed by the BSP.
#### 3.2.1. Assumptions
We make the following assumptions for our threat model: we assume that the enclave itself is trusted including the hardware-backed attestation provided by the TEE. We assume that the transparency log is trustworthy as potential tampering attempts are detectable. We also assume that the transparency log is protected against split-view attacks by having sufficient witnesses in place.
#### 3.2.2. Adversary modeling
The following list defines relevant adversary models, including information about the respective attack surface, in accordance to the scope of our research.
1. Physical adversary Adversary with physical access to hardware, including storage, or the respective infrastructure. We assume that a physical adversary could also be an insider (A3), as our threat model does not distinguish between attacks that require physical access, regardless of whether the attacker is external or internal.
1. On-path adversary (OPA) An on-path adversary has access to the network infrastructure (e.g., via a machine-in-the-middle [MitM] attack) and is capable of modifying code, the attestation data, or the artifact sent within that network.
1. Insider adversary An insider adversary can be a privileged employee working with access to the platform layer such as the hypervisor of the CSP running the VMs or the hosting environment (e.g., docker host) of the BSP. This category of adversary includes malicious service providers. Physical attacks are covered through A1.
#### 3.2.3. Threats
We introduce threats for generic build systems that we considered while designing A-Bs. The following section on architecture explains how A-Bs effectively mitigates these.
1. Compromise the build server: An adversary (A1, A3) might compromise the build server infrastructure by modifying aspects of the build process, including source code, which could result in a malicious build artifact. This threat addresses all kinds of unauthorized modifications during the build process, such as directly manipulating the source code, the respective build scripts (e.g., shell scripts triggering the build), or parts of the build machine itself, like the OS.
1. Cross-tenant threats: Any adversary that uses shared infrastructure might use its privilege to temporarily or permanently compromise the host and thus affect subsequent or parallel builds. It also potentially renders any response from the service untrustworthy. This is particularly important for build processes as they generally allow developers to execute arbitrary code.
1. Implant a backdoor in code or assets: An adversary (A3) might implant a backdoor within the repository through intentionally incorrect code or within files that are committed as binary assets. For this to be successful the adversary might need to successfully execute social engineering attack to become co-maintainer on an open-source repository. An example of this is the compromise of XZ Utils (Lins et al., 2024) which we discuss in Section 7. Unlike T1, implanting a backdoor in this manner does not directly compromise the build process itself, but rather is an orthogonal supply chain concern.
1. Spoofing the repository: An adversary might clone an open-source project, introduce malicious modifications, and attempt to make it appear as the original repository as shown in recent attacks (Harush, 2025). This is similar to typo-squatting of dependencies in package managers (Neupane et al., 2023; Taylor et al., 2020). A common mitigation of such threats is the use of digital signatures for signing the artifact. However, an insider adversary (A3) might be able to exfiltrate such a key.
1. Compromise build assets during transmission: An adversary with network access (A2) might compromise build assets (e.g., source code, dependencies, configuration, …) transferred between the parties involved in the build process by intercepting the network traffic.We consider well-resourced adversaries that might issue valid SSL certificates or compromise the servers of any other party. This threat does also include side-loading potentially malicious libraries from external sources.
1. Compromise the hardware layer: An adversary with physical access (A1) might perform classical physical attacks such as interrupting execution, intercepting access to the RAM, and running arbitrary code on the CPU cores that are not part of a secure enclave. This aligns with the threat model of Confidential Computing technologies although they all vary slightly and they do have known vulnerabilities.
1. Undermine verification results: An adversary (A1, A2, A3) can undermine verification results, e.g., authenticity or integrity checks, by manipulating verification data either directly in the infrastructure or while in transit. Similarly, an adversary (A2) might pursue a split-view attack where some users are given different results for queries against central logs.
### 3.3. Architecture
We designed A-Bs with cloud-based CI/CD pipelines in mind. In particular, such a system can be provided by a BSP who rents infrastructure from an untrusted CSP (see Figure 1). Our design is compatible with different Confidential Computing technologies. While our practical implementation (§ 4) uses a particular technology, we describe our architecture and its design challenges in general terms (e.g., TEE, sandbox). Figure 2 provides an architectural overview which is described in more detail in this section.
<details>
<summary>x2.png Details</summary>

### Visual Description
## System Architecture Diagram: Secure Build Attestation Pipeline
### Overview
This image is a technical system architecture diagram illustrating a secure, verifiable software build pipeline. The process uses a Trusted Execution Environment (TEE) and a hardware trust anchor to generate cryptographic attestations linking a built software artifact to its source code commit. The diagram details the flow of control, data, and cryptographic proofs between various components, from build initiation to final verification by an end-user.
### Components/Axes
The diagram is organized into several key regions and components:
**1. External Entities & Triggers (Outside the main dashed box):**
* **Top-Left:** `build trigger` (icon of a person with a wrench). Arrow labeled **1** points to the Instance manager.
* **Top-Right:** `Hardware Trust Anchor (e.g., AWS Nitro Card)` (green box). Receives attestation request (arrow **7**).
* **Right Side:** `RHP (e.g., GitHub)` (cylinder icon). Source code repository. Arrow **4** shows download of repository.
* **Bottom-Left:** `Log` (cylinder icon). Receives published attestation document `AT` (arrow **9**).
* **Bottom-Right:** Artifact repository (cylinder icon). Receives published artifact `A` and attestation `AT` (arrow **9**).
* **Bottom-Center:** End-user/verifier (icon of a person with checkmark/cross). Performs steps **10** and **11**.
**2. Host Instance (Large dashed box labeled `Host instance (e.g., AWS EC2)`):**
* **Left Component:** `Instance manager` (vertical rectangle). Orchestrates the build process.
* **Central Component:** `TEE (e.g., Nitro Enclave)` (green shaded area). The secure environment where the build occurs.
* **TEE Sub-component:** `Enclave client` (vertical rectangle). Manages the build runner.
* **TEE Sub-component:** `Sandbox (containerd/gVisor)` (pink shaded area within the green TEE). Isolates the untrusted build process.
* **Inside Sandbox:** `Build runner` (white box). Executes the trusted parts of the build.
* **Inside Sandbox:** `Untrusted build process` (pink box containing three smaller white boxes connected by arrows). Performs the actual compilation/build steps.
**3. Data Elements & Labels:**
* **CT:** Commit Hash (reported by Build runner in step **5**).
* **A:** Artifact Hash (reported by Untrusted build process in step **6**).
* **AT:** Attestation Document (result of step **7**, shared in step **8**, published in step **9**).
* **PCR0-2:** Platform Configuration Registers (part of the attestation in step **7**).
* **.eif:** File format (likely Enclave Image Format) used to start the enclave (step **2**).
### Detailed Analysis
The process flow is explicitly numbered from **1** to **11**:
1. **Build Trigger:** An external trigger initiates the process.
2. **Start Enclave:** The Instance manager starts the Enclave client within the TEE, providing a `.eif` file.
3. **Start Build Runner:** The Enclave client starts the Build runner inside the sandbox.
4. **Download Source:** The Build runner downloads the repository (including build files) from the RHP (e.g., GitHub).
5. **Report Commit Hash (CT):** The Build runner reports the commit hash `CT` back to the Enclave client.
6. **Report Artifact Hash (A):** The Untrusted build process, after completing its steps, reports the final artifact hash `A` to the Enclave client.
7. **Attestation:** The Enclave client requests an attestation from the Hardware Trust Anchor over the set `{PCR0-2, CT, A}`. This results in the creation of a signed attestation document `AT`.
8. **Share Attestation:** The attestation document `AT` is shared from the Enclave client back to the Instance manager and also to the Untrusted build process.
9. **Publish:** The Instance manager publishes `AT` to a Log. The Untrusted build process publishes the final artifact `A` along with its attestation `AT` to an artifact repository.
10. **Download & Claim:** An end-user downloads the artifact `A` and the associated claim: `"A was built using PCR0-2 from CT"`.
11. **Verify Proof:** The end-user requests and verifies the proof for the claim against the Log (and optionally checks for endorsements and revocations).
### Key Observations
* **Trust Boundary:** A clear trust boundary is established by the green `TEE` box. The `Untrusted build process` is further isolated within a `Sandbox` inside the TEE.
* **Critical Data Flow:** The Enclave client acts as a central hub, collecting `CT` and `A` before requesting the attestation `AT`. The attestation cryptographically binds the hardware state (`PCR0-2`), the source (`CT`), and the output (`A`).
* **Dual Publishing:** The attestation `AT` is published to a separate, immutable Log (step **9**, left) for independent verification, while the artifact `A` and its attestation are published together for distribution (step **9**, right).
* **Verification Loop:** The process concludes with an external verifier (steps **10 & 11**) who can independently check the claim by retrieving the proof from the Log, completing the chain of trust.
### Interpretation
This diagram depicts a **verifiable build system** designed to provide strong cryptographic guarantees about software supply chain integrity. The core innovation is the use of a hardware-backed TEE to create an unforgeable link (`AT`) between the source code commit (`CT`) and the resulting binary (`A`).
* **What it demonstrates:** It shows how to solve the "trusted build" problem. Even if the build environment is compromised, the attestation from the hardware trust anchor proves that the specific artifact `A` was generated from the specific source `CT` within a measured, known environment (`PCR0-2`).
* **Relationships:** The flow is linear and causal. Each step depends on the successful completion of the previous one. The Instance manager orchestrates, the TEE executes securely, and the external repositories and logs provide persistence and verification points.
* **Notable Design Choices:** The separation of the "Build runner" (trusted, reports `CT`) from the "Untrusted build process" (untrusted, reports `A`) within the sandbox is a key security pattern. It acknowledges that parts of the build toolchain may be untrustworthy but contains their impact. Publishing the attestation to a separate log enables transparency and third-party auditing.
* **Implication:** This architecture is foundational for high-assurance software distribution, allowing users to verify that the software they are running matches the public source code and was built in a controlled manner, mitigating risks of supply chain attacks.
</details>
Figure 2. Overview of the protocol steps during build and verification. Dashed borders indicate separate or sandboxed execution environment. Only the TEE and the hardware trust anchor are fully trusted. 1 The build process is triggered manually or as a result of code changes. Either will cause a webhook call to the Instance Manager. 2 The Instance Manager starts an fresh enclave from a publicly known .eif file with the measurements PCR0-2. 3 Once booted, the Enclave Client starts the inner sandbox. 4 The sandbox executes the action runner which fetches the repository snapshot. That snapshot includes both the source code and build instructions. 5 A hash of the snapshot is reported to the Enclave Client for safeguarding. Now the build process is started which is untrusted. 6 Once it finishes, the sandbox reports the hash of the produced artifact. 7 The Enclave Client then requests an attestation document from the Nitro Card covering PCR0-2, the repository snapshot hash, and the artifact hash. 8 The results are shared with both the build process and the outer Instance Manager. 9 The build process can now publish the artifact and certificate. And the Instance Manager publishes the attestation. 10 When a user downloads the artifact, it can contain a certificate specifying how it was build. 11 The user can verify this certificate by checking that it is included in the public transparency log.
The core unit of an A-B system is the host instance which runs control software, the instance manager, and can start our TEE. Each build request is forwarded to an instance manager which then starts a fresh enclave from a public image inside the TEE. These images are available as open-source and therefore have known PCR values that can later be attested to.
The TEE provides both confidentiality and integrity of data-in-use through hardware-backed encryption of memory which protects it from being read or modified—even from adversaries with physical access, the host, and the hypervisor. The enclave will later use remote attestation to verify that it has booted a particular secure image in a secure context. These guarantees mitigate T1 and are essential to the integrity of the final attestation. However, it alone is not sufficient, as otherwise the build process might manipulate its internal state, and thus the input we are later attesting to. Therefore, we designed a protocol with an integrity-protected observer, the Enclave Client, that interacts with a sandbox that is embedded inside the TEE.
Once the enclave has booted, it starts the Enclave Client. As it runs inside the TEE, we can assume that it is integrity-protected. The Enclave Client first establishes a bi-directional communication channel with the Instance Manager outside the TEE via shared memory. Through this channel, the Instance Manager provides short-lived authentication tokens for accessing the repository at the RHP and receives updates about the build process.
The Enclave Client then manages a sandbox inside the enclave. The sandbox ensures that the untrusted build process (which might execute arbitrary build steps and code) cannot modify the important state kept by the Enclave Client. In particular, we need to protect the initial measurement of the received source code files and build instructions. This mitigates T2. The sandbox optionally captures complete, attested, logs of all incoming and outgoing communication of the build execution, which can help audits and investigations.
Once the sandbox has started, the Enclave Client forwards a short-lived authentication token to the build runner inside the sandbox. The build runner uses the token to fetch both the code and build instructions from the RHP. Since the enclave has no direct internet access, all TCP/IP communication is tunneled via shared memory as well. Upon downloading the source code and instructions, the sandbox computes the commit hash CT and reports to the Enclave Client. The commit hash not only covers the content of the code and build instructions, but also the repository metadata. This includes the individual commit messages which can include signatures with the developers private keys (project, 2024b). By checking and verifying these during the build steps, the system also attests to the origin of the source code, i.e. the latest developer implicitly signs-off on the current repository state at this commit. This mitigates T5.
Once the commit hash has been committed to the Enclave Client, the sandbox starts the build process by executing the build instructions from the repository—and from that moment we consider the inner state sandbox untrusted. The sandbox expects the build process to eventually report the path of the artifact that it intends to publish. Once the build process is complete, the sandbox computes the hash A of the artifact and forwards it to the Enclave Client. Note: while the inner state of the sandbox is untrusted, the Enclave Client as an integrity-protected observer has safeguarded the input measurements (CT) from manipulation. A ratcheting mechanism ensures that it will only accept CT once at the beginning from the build runner before any untrusted processes are started inside the sandbox. The hash of the artifact (A) can be received from the untrusted build process as it will be later compared by the user against the received artifact.
The Enclave Client then uses the TEE attestation mechanism to request an attestation document AT over the booted image PCR values (including both the Enclave Client and the sandbox image), the initial input measurement CT, and the artifact hash A. The response AT is then shared with the sandbox, so that the build process can include it with the published artifact, published to the transparency log. Together with proper verification by the client this mitigates T7.
Importantly, the transparency log ensures that revocation notices (e.g., after discovering hardware vulnerabilities) are visible to all users. By requiring up-to-date inclusion proofs for artifacts, the end consumer can efficiently verify that they still considered secure. As such, it lessens the impact of T3 and T6. Furthermore, transparency logs allow the developer to monitor for leaked signing keys. They assure users that observed rotations of signing keys are intentional as they know that developers are being notified about them as well. This mitigates T4.
After completion, the enclave is destroyed. This makes the build process stateless which simplifies debugging and reasoning about its life cycle and helps in mitigating T2, T6. Its stateless nature and the clear control of the ingoing code and build instructions ensures that the build is hermetic, i.e. the build cannot accidentally rely on unintended environmental information. Note that the main build process generally does not require any modifications if it already works with a compatible build runner—it is simply being executed in a sandbox inside an integrity-protected environment. The developer will only need to add a final step to communicate the artifact path and receive the attestation document AD.
### 3.4. Composing A-Bs and R-Bs
We believe that combining our A-Bs and classic R-Bs improves build ergonomics and increases trust. R-Bs can easily consume A-B artifacts and commit to a hash of the artifact similar to lockfiles that are already used by dependency managers such as Rust’s cargo and JavaScript’s NPM. Similarly, A-Bs can consume R-B artifact and even be independent R-B builders themselves. Due to the attested and controlled environment, existing R-B projects might be able to rely on fewer independent builders when A-Bs are used.
This allows for a setup where the independent builders of an R-B project are distributed across attestable builders running on machines using hardware from different Confidential Computing vendors (see Figure 3). In this setting, the guarantees of the R-B imply an anytrust model that is easily verified. The verifier can use the log to ensure they get a correct build as long as they trust at least one of the Confidential Computing vendors—without having to decide which one. The reader might find it interesting to compare this with how anonymity networks like mix nets and Tor work where traffic is routed through multiple hops and the unlinkability property holds as long as one of them is trusted.
<details>
<summary>x3.png Details</summary>

### Visual Description
## System Architecture Diagram: Parallel Blockchain Processing Pipeline
### Overview
The image is a technical system architecture diagram illustrating a parallel processing workflow, likely for a blockchain or distributed ledger system. It depicts a source code file being processed by three parallel services, each generating an output that is stored in a shared ledger, which is then accessible by an end-user. The diagram uses symbolic icons and labels to represent components and data flow.
### Components/Axes
The diagram is organized into three main vertical sections from left to right:
1. **Input Section (Left):**
* A single icon representing a source code file, labeled with the symbol `</>`.
2. **Processing Section (Middle):**
* Three parallel processing paths, each consisting of:
* A **cloud-gear icon** (representing a service or compute node). These are labeled **B1** (blue), **B2** (green), and **B3** (yellow/orange).
* A **cube icon** (representing a block, transaction, or data object). Each cube is associated with the same hexadecimal address: `0xfe1423cd...`.
3. **Storage & User Section (Right):**
* A **cylinder icon** labeled **L**, representing a ledger or database.
* A **user icon** (person silhouette) below the ledger.
* Three **file icons** above the ledger, labeled **C1** (blue), **C2** (green), and **C3** (yellow/orange).
**Flow & Connections:**
* A solid arrow points from the source code file (`</>`) to each of the three cloud-gear icons (B1, B2, B3).
* Solid arrows point from each cloud-gear icon to its corresponding cube icon.
* A **dotted line** originates from the source code file, travels upward, then rightward across the top of the diagram, and terminates with an arrow pointing down into the ledger (`L`). This line passes through the three file icons (C1, C2, C3).
* A **bidirectional arrow** connects the ledger (`L`) and the user icon, indicating read/write access.
### Detailed Analysis
* **Component Labels & Text:**
* Source Code File: `</>`
* Service/Node Labels: `B1`, `B2`, `B3`
* Output Object Address: `0xfe1423cd...` (identical for all three cubes)
* Ledger Label: `L`
* File/Configuration Labels: `C1`, `C2`, `C3`
* **Color Coding & Spatial Grounding:**
* The color of the cloud-gear icon (B1=blue, B2=green, B3=yellow) matches the color of its corresponding file icon (C1=blue, C2=green, C3=yellow) located in the top-right. This establishes a direct visual link between each processing service and its associated configuration or output file.
* The three cube icons and their hex addresses are positioned vertically in the center of the diagram.
* The ledger (`L`) is positioned in the top-right quadrant. The user icon is directly below it in the bottom-right.
* **Data Flow Interpretation:**
1. A single source code artifact (`</>`) is deployed or sent to three parallel services (B1, B2, B3).
2. Each service processes the input and produces an output object (represented by the cube), all referencing the same contract or data address (`0xfe1423cd...`).
3. A separate, dotted-line flow suggests that metadata, configuration, or results (C1, C2, C3) associated with the source code are also sent to the ledger (`L`).
4. The final ledger (`L`) aggregates data from all three processing paths and is accessible to the end-user.
### Key Observations
1. **Identical Output Addresses:** All three processing paths (B1, B2, B3) produce outputs linked to the same hexadecimal address (`0xfe1423cd...`). This is a critical observation. It could indicate:
* The deployment of the same smart contract to three different nodes or shards.
* Three parallel transactions interacting with the same contract address.
* A simplification in the diagram where the address is a placeholder.
2. **Dual Data Pathways:** The diagram explicitly shows two distinct data flows from the source code: a primary processing flow (solid arrows through B1-B3) and a secondary metadata/configuration flow (dotted line through C1-C3).
3. **Color-Coded Association:** The consistent color pairing between service icons (B-series) and file icons (C-series) is a deliberate design choice to show relationship without explicit connecting lines.
4. **Centralized Ledger:** Despite parallel processing, all data converges into a single ledger (`L`), which serves as the unified interface for the user.
### Interpretation
This diagram illustrates a **scalable or fault-tolerant processing pattern** for blockchain-based applications. The core concept is distributing the workload from a single source (e.g., a dApp frontend, a contract factory) across multiple identical services (B1, B2, B3). This could represent:
* **Sharding:** Processing transactions in parallel across different shards.
* **Redundancy/Fault Tolerance:** Running the same process on multiple nodes for reliability.
* **Load Balancing:** Distributing user requests to prevent any single node from being overwhelmed.
The identical hex address (`0xfe1423cd...`) is the most significant technical detail. It strongly suggests that the system is interacting with a **single, canonical smart contract or data structure** on the ledger, even though the computation is parallelized. The services (B1-B3) are likely stateless processors or validators executing logic related to that central contract.
The dotted line with files C1-C3 represents an important ancillary process—perhaps logging, emitting events, or storing configuration artifacts—that happens independently of the main transaction flow but is crucial for auditability or system setup. The bidirectional arrow between the ledger and user confirms the system's purpose: to provide users with a consistent, aggregated view of the state managed by the distributed backend.
**In summary, the diagram depicts a pattern where a single codebase is executed in parallel by multiple services to interact with a common on-chain resource, with results and metadata aggregated into a user-accessible ledger.** The design emphasizes parallelism, a single source of truth (the ledger), and clear separation between processing and storage.
</details>
Figure 3. Three attestable builders using different hardware vendors (e.g., Intel, AMD, Arm) perform the same R-B resulting in identical artifacts. The user is then hedged against up to two backdoored TEEs (§ 3.4).
The trust of A-Bs depends on the trust of their build image. While the final artifact (or rather its measurement) is attested to and included in the certificate, we rely on the initial image of the machine embedded in the TEE to ensure the correct and secure execution of the build instructions of the source code snapshot. We believe that R-Bs are also important for bootstrapping an A-B system. Even where the base image can be produced using A-Bs, the very first image should be created using R-Bs and bootstrapped from as little code as possible. Projects like Bootstrappable Build (project, 2024b) lay the foundation for this approach. In the long run, these R-Bs can be executed by attestable builders as described above.
## 4. Practical evaluation
We implemented the A-B architecture (§ 3.3) to demonstrate its feasibility and to practically evaluate its performance overhead.
### 4.1. Implementation
Our prototype uses AWS Nitro Enclaves (web services, 2024) as the underlying Confidential Computing technology due the availability of accessible tooling. However, it is also possible to achieve similar guarantees with other technologies. For instance, AMD SEV-SNP might offer security benefits due to a smaller Trusted Computing Base (TCB) and we leave this as an engineering challenge for future work.
AWS Nitro Enclaves are started from EC2 host instances and provide hardware-backed isolation from both the host operation system and the hypervisor through the use of dedicated Nitro Cards. These cards assign each enclave dedicated resources such as main memory and CPU cores that are then no longer accessible to the rest of the system. Enclaves boot a .eif image that can be generated from Docker images. Creation of these images yields PCR0-2 In the AWS Nitro architecture the values PCR0, PCR1, and PCR2 cover the entire .eif image and can be computed during its build process. values that can later be attested to.
Since enclaves do not have direct access to other hardware, such as networking devices, all communication has to be done via vsock sockets that leverage shared memory. These provide bi-directional channels that we use to (a) exchange application layer messages between the instance manager and enclave client and (b) tunnel TCP/IP access for the build runner to the code repository.
We implemented two sandbox variants using the lightweight container runtime containerd and the hardened gVisor (gVisor Authors, 2025) runtime which has a compatible API. Parameters for the sandbox, such as the short-lived authentication tokens for accessing the repository, are passed as environment variables. Internet access is mediated via Linux network namespaces and results are communicated via a shared log file. We pass only limited capabilities to the sandbox and the runtime immediately drops the execution context to an unprivileged user. gVisor provides additional guarantees by intercepting all system calls. Optionally, this setup can be further hardened using SELinux, seccomp-bpf, and similar.
As we want to demonstrate ease-of-adoption, we integrated with GitHub Actions. The Instance Manager exposes a webhook to learn about newly scheduled build workflows and short-lived credentials are acquired using narrowly-scoped personal access tokens (PAT). Inside the sandbox runs an unmodified GitHub Action Runner (v2.232.0) that is provided by GitHub for self-hosted build platforms. As such, developers only need to export a PAT, add our webhook, and perform minor edits in their .yml files (see Appendix B) which include updating the runner name and calling the attestation script.
Most components are written in Rust and we leverage its safety features to minimize the overall attack surfaces and avoid logic errors, e.g., through the use of Typestate Patterns (Biffle, 2024) and similar. Our implementation consists of less than 5 000 lines of open source code and is available at: https://github.com/lambdapioneer/attestable-builds.
### 4.2. Build targets
We demonstrate the feasibility of the A-B approach by building software that appears to be challenging. First, we build five of the still unreproducible Debian packages. We start with a list of all unreproducible packages, choose the ones with the fewest but at least two dependencies (to rule out trivial packages), and then use apt-rdepends -r to identify those with the most reverse dependencies, i.e. which likely have a large impact on the build graph. In addition, we add one with more dependencies. This results in the following five packages: ipxe, hello, gprolog, scheme48, and neovim. Second, we build large software projects including the Linux Kernel (kernel, 6.8.0, default config) and the LLVM Clang (clang, 18.1.3). These show that our A-Bs can accommodate complex builds and these two artifacts are also essential for later bootstrapping the base image itself, as these are the versions used in Ubuntu 24.04. Finally, we augment this set by including tinyCC (a bootstrappable C compiler), libsodium (a popular cryptographic library), xz-utils, and our own verifier client.
For reproducibility, we include copies of the source code and build instructions in a secondary repository with separate branches for each project. The C-based projects follow a classic configure and make approach and the Rust-based projects download dependencies during the configuration step.
### 4.3. Measurements
<details>
<summary>x4.png Details</summary>

### Visual Description
\n
## Stacked Bar Chart: Build Duration Comparison Across Software Projects
### Overview
The image displays a series of nine stacked bar charts arranged horizontally. Each chart compares the overall build duration (in seconds) for a specific software project under three different configurations or environments labeled "HS", "ES", and "ES+". The charts collectively analyze the performance impact of these configurations across a diverse set of software.
### Components/Axes
* **Main Title (Implicit):** The overall figure compares build durations. Each subplot has a specific title.
* **Subplot Titles (Top of each chart, from left to right):**
1. GProlog (1.6.0)
2. Hello (2.10)
3. IPXE (1.21.1)
4. Scheme48 (1.9.3)
5. NeoVIM (0.11.0)
6. LibSodium (1.0.20)
7. TinyCC (0.9.28)
8. Verifier Client
9. XZ Utils (5.6.3)
* **Y-Axis (Leftmost chart only):** Label: "Overall duration (s)". Scale: 0 to 500, with major tick marks at 0, 100, 200, 300, 400, 500.
* **X-Axis (Each subplot):** Three categorical labels: "HS", "ES", "ES+".
* **Legend (Bottom center of the entire figure):** Six color-coded categories representing components of the total duration:
* **Start EIF:** Dark Blue
* **Boot:** Light Blue
* **Runner init:** Orange
* **Checkout:** Light Orange
* **Configure:** Light Green
* **Build:** Dark Green
### Detailed Analysis
The data is presented as stacked bars. The total height of each bar represents the "Overall duration". The colored segments within each bar represent the time spent on the six components defined in the legend. The "Build" (dark green) component is consistently the largest or one of the largest segments across all projects and configurations.
**Per-Project Analysis (Approximate values, read from the chart):**
1. **GProlog (1.6.0):**
* **HS:** Very low total duration (~20s). Primarily "Build" (dark green).
* **ES:** Increased total (~60s). Visible segments: "Boot" (light blue, ~20s), "Configure" (light green, ~10s), "Build" (dark green, ~30s).
* **ES+:** Slightly higher than ES (~80s). Similar segment distribution to ES.
2. **Hello (2.10):**
* **HS:** Very low total (~15s). Mostly "Build".
* **ES:** Total ~50s. "Boot" (~20s), "Configure" (~10s), "Build" (~20s).
* **ES+:** Highest total (~90s). "Boot" (~20s), "Configure" (~30s), "Build" (~40s).
3. **IPXE (1.21.1):**
* **HS:** Moderate total (~55s). Almost entirely "Build".
* **ES:** Higher total (~90s). "Boot" (~20s), "Build" (~70s).
* **ES+:** Significantly higher total (~240s). "Boot" (~20s), "Configure" (~20s), "Build" (~200s).
4. **Scheme48 (1.9.3):**
* **HS:** Low total (~20s). Mostly "Build".
* **ES:** Total ~60s. "Boot" (~20s), "Configure" (~10s), "Build" (~30s).
* **ES+:** Total ~75s. "Boot" (~20s), "Configure" (~15s), "Build" (~40s).
5. **NeoVIM (0.11.0):**
* **HS:** High total (~260s). "Configure" (~80s), "Build" (~180s).
* **ES:** Higher total (~280s). "Boot" (~20s), "Configure" (~80s), "Build" (~180s).
* **ES+:** Very high total (~490s). "Boot" (~20s), "Configure" (~160s), "Build" (~310s).
6. **LibSodium (1.0.20):**
* **HS:** Low total (~40s). Mostly "Build".
* **ES:** Total ~70s. "Boot" (~20s), "Configure" (~10s), "Build" (~40s).
* **ES+:** Higher total (~185s). "Boot" (~20s), "Configure" (~60s), "Build" (~105s).
7. **TinyCC (0.9.28):**
* **HS:** Very low total (~10s). Mostly "Build".
* **ES:** Low total (~45s). "Boot" (~20s), "Configure" (~10s), "Build" (~15s).
* **ES+:** Slightly higher total (~55s). "Boot" (~20s), "Configure" (~15s), "Build" (~20s).
8. **Verifier Client:**
* **HS:** Moderate total (~80s). Almost entirely "Build".
* **ES:** Higher total (~110s). "Boot" (~20s), "Build" (~90s).
* **ES+:** Highest total (~160s). "Boot" (~20s), "Configure" (~20s), "Build" (~120s).
9. **XZ Utils (5.6.3):**
* **HS:** Low total (~30s). Mostly "Build".
* **ES:** Total ~60s. "Boot" (~20s), "Configure" (~10s), "Build" (~30s).
* **ES+:** Higher total (~155s). "Boot" (~20s), "Configure" (~60s), "Build" (~75s).
### Key Observations
1. **Consistent Trend:** For every single software project, the total duration increases from HS to ES, and again from ES to ES+. The ES+ configuration is always the slowest.
2. **Dominant Component:** The "Build" (dark green) phase is the primary contributor to total duration in nearly all cases, especially for HS configurations.
3. **Emergence of "Configure":** The "Configure" (light green) component becomes significantly more prominent in the ES and ES+ configurations for many projects (e.g., NeoVIM, LibSodium, XZ Utils, IPXE).
4. **Stable "Boot" Time:** The "Boot" (light blue) component appears to have a relatively constant duration (~20s) across all projects and configurations where it is visible (ES and ES+).
5. **Project Variability:** The absolute scale of duration varies greatly. NeoVIM is an order of magnitude slower than TinyCC. The impact of moving to ES+ is most dramatic for IPXE and NeoVIM in absolute terms.
### Interpretation
This chart demonstrates the performance overhead associated with different execution environments (HS, ES, ES+) for building software. The data suggests:
* **HS (likely "Host System" or similar)** is the baseline, fastest configuration, relying almost entirely on the native "Build" process.
* **ES (likely "Execution Environment" or "Emulated System")** introduces consistent overhead, primarily from a "Boot" phase and an increased "Configure" phase, leading to a moderate increase in total build time.
* **ES+ (an enhanced or more isolated ES)** adds substantial overhead, most notably a dramatically expanded "Configure" phase and often a larger "Build" phase. This could indicate more complex environment setup, additional security checks, or less optimized code paths in this configuration.
* The **"Build" phase itself scales poorly** in the ES+ environment for complex projects like NeoVIM and IPXE, suggesting that the environment's constraints significantly impact the core compilation task.
* The **consistency of the "Boot" time** suggests it's a fixed-cost operation for the ES/ES+ environments, independent of the software being built.
The investigation reveals a clear trade-off: the ES/ES+ environments (which may offer benefits like security, isolation, or reproducibility) come at a significant and variable cost in build performance, primarily driven by configuration and build-time inflation. Project complexity (e.g., NeoVIM vs. Hello) is a major factor in how severely this overhead is felt.
</details>
Figure 4. The duration of individual steps for the evaluated projects including the five unreproducible Debian packages and other artifacts. HS represents the baseline with a sandbox running directly on the host, ES (using containerd) and ES+ (using gVisor) are variants of our A-B prototype executing a sandboxed runner within an enclave. See Figure 12 for a larger version.
We build most targets on m5a.2xlarge EC2 instances (8 vCPUs, 32 GiB). However, for kernel and clang we use m5a.8xlarge EC2 instances (32 vCPUs, 128 GiB). To allow fair comparison between executions inside and outside the enclave, we assign half the CPUs and memory to the enclave. At time of writing, the m5a.2xlarge instances cost around $0.34 per hour For comparison: the 4-core Linux runner offered by GitHub costs $0.016 per minute ($0.96 per hour).. We minimize the impact of I/O bottlenecks by increasing the underlying storage limits to 1000 MiB/s and 10 000 operations/s which incurs extra charges.
In order to better understand how the enclave and the sandbox implementations impact performance, we repeat our experiments across three configurations. The host-sandbox (HS) configuration runs the GitHub Runner using containerd on the host and serves as baseline representing a self-hosted build server. We evaluate two A-B compatible configurations: the enclave-sandbox (ES) variant uses the standard containerd runtime and the hardened enclave-sandbox-plus (ES+) variant uses gVisor. For kernel and clang we additionally include H and E configurations without sandboxes.
We are interested in the impact of A-Bs on the duration of typical CI tasks. For this we have instrumented our components to add timestamps to a log file. We extract the following steps: Start EIF allocates the TEE and loads the .eif file into the enclave memory; then the Boot process starts this image inside the TEE; subsequently the Runner init connects to GitHub and performs the source code Checkout; finally, the build file performs first a Configure step and then executes the Build. We run each combination of build target and configuration three times and report the average.
Figure 4 plots these durations for the unreproducible Debian packages and the additional targets that we have picked (§ 4.2). See Appendix D for Table 5 which contains all measurements (also for other configurations). For small builds, the overall duration is dominated by the time required to start and boot the enclave. Together these two steps typically take around 37.6 seconds for our .eif file that weighs 1 473 MiB. These start-up costs can be mitigated by pre-warming enclaves (§ 7).
For small targets we found that the build duration effectively decreases between HS and ES configurations. For instance, the NeoVIM build duration (the green bars in Figure 4) drop from 184.9 s (HS) to 167.3 s (ES, -10% over HS). We believe that the enclave is faster because it entirely in memory and therefore mimicks a RAM-disk mounted build with high I/O performance. Again, gVisor (ES+) has a large impact and can increase the build times significantly, e.g., NeoVIM takes 311.7 s (ES+, +69% over HS).
The costs for initializing the build runner and checking out the source code are typically less than 9 seconds overall. Even though all IP traffic is tunneled via shared memory using vsock, the difference between host-based and enclave-based configurations is small. In fact, for large projects the check-out times sometimes even drops, e.g., clang from 148.0 s (HS) to 117.2 s (ES). We believe that the involved Git operations become I/O bound at this size. However, using gVisor (ES+) imposes a overhead for the checkout of up-to 2 s for small targets and the checkout of the large clang target increases from 117.2 s (ES) to 132.8 s (ES+).
<details>
<summary>x5.png Details</summary>

### Visual Description
## Line Charts: Build Duration vs. Number of Parallel Jobs
### Overview
The image contains two side-by-side line charts comparing the build duration (in seconds) of two software projects ("XZ Utils" and "Verifier Client") as a function of the number of parallel jobs used during compilation (specified via `make -j`). Each chart plots two data series: "HS" (solid green line) and "ES+" (dashed green line).
### Components/Axes
* **Chart Titles:**
* Left Chart: "XZ Utils"
* Right Chart: "Verifier Client"
* **Y-Axis (Both Charts):** Label: "Build duration (s)". The scale differs between charts.
* XZ Utils: Ticks at 25, 50, 75. Range appears to be 0 to ~90.
* Verifier Client: Ticks at 100, 200. Range appears to be 0 to ~250.
* **X-Axis (Both Charts):** Label: "Num jobs (make -j)". Ticks at integer values from 1 to 8.
* **Legend:** Located in the top-right corner of the "Verifier Client" chart.
* **HS:** Represented by a solid green line.
* **ES+:** Represented by a dashed green line.
### Detailed Analysis
#### Chart 1: XZ Utils
* **HS Series (Solid Green Line):**
* **Trend:** Sharp initial decrease, followed by a gradual decline that plateaus.
* **Data Points (Approximate):**
* 1 job: ~45 seconds
* 2 jobs: ~25 seconds
* 3 jobs: ~20 seconds
* 4 jobs: ~18 seconds
* 5 jobs: ~17 seconds
* 6 jobs: ~16 seconds
* 7 jobs: ~16 seconds
* 8 jobs: ~16 seconds
* **ES+ Series (Dashed Green Line):**
* **Trend:** Sharp initial decrease, followed by a very slight, steady increase.
* **Data Points (Approximate):**
* 1 job: ~85 seconds
* 2 jobs: ~70 seconds
* 3 jobs: ~68 seconds
* 4 jobs: ~70 seconds
* 5 jobs: ~72 seconds
* 6 jobs: ~73 seconds
* 7 jobs: ~74 seconds
* 8 jobs: ~75 seconds
#### Chart 2: Verifier Client
* **HS Series (Solid Green Line):**
* **Trend:** Sharp initial decrease, followed by a gradual decline that plateaus.
* **Data Points (Approximate):**
* 1 job: ~180 seconds
* 2 jobs: ~100 seconds
* 3 jobs: ~80 seconds
* 4 jobs: ~70 seconds
* 5 jobs: ~70 seconds
* 6 jobs: ~70 seconds
* 7 jobs: ~70 seconds
* 8 jobs: ~70 seconds
* **ES+ Series (Dashed Green Line):**
* **Trend:** Sharp initial decrease, followed by a plateau with a very slight upward trend.
* **Data Points (Approximate):**
* 1 job: ~220 seconds
* 2 jobs: ~140 seconds
* 3 jobs: ~115 seconds
* 4 jobs: ~110 seconds
* 5 jobs: ~112 seconds
* 6 jobs: ~115 seconds
* 7 jobs: ~118 seconds
* 8 jobs: ~120 seconds
### Key Observations
1. **Consistent Pattern:** Both projects and both build configurations (HS, ES+) show a significant reduction in build time when moving from 1 to 2 parallel jobs.
2. **Diminishing Returns:** The benefit of adding more parallel jobs diminishes rapidly after 2-4 jobs. For the HS configuration, build time largely plateaus after 4 jobs. For the ES+ configuration, the time stabilizes or even increases slightly beyond 3-4 jobs.
3. **Performance Gap:** The ES+ configuration consistently has a higher build duration than the HS configuration across all job counts for both projects. The gap is larger in absolute seconds for the Verifier Client.
4. **Project Scale:** The Verifier Client has a significantly longer base build time (at 1 job) than XZ Utils for both configurations, indicating a larger or more complex codebase.
### Interpretation
The data demonstrates the effect of parallel compilation on build performance. The initial steep drop confirms that both projects benefit from parallelization. However, the plateauing and slight increase in the ES+ lines suggest that beyond an optimal point (around 3-4 jobs), the overhead of managing parallel tasks (e.g., context switching, resource contention, dependency synchronization) begins to outweigh the benefits of adding more concurrent processes.
The consistent performance difference between HS and ES+ implies that the ES+ configuration involves additional, time-consuming steps (perhaps more extensive verification, instrumentation, or different compiler flags) that are not fully parallelizable or add fixed overhead. The fact that the pattern is similar across two different projects suggests this is a characteristic of the build configurations themselves, not a project-specific anomaly. For optimal build efficiency, using the HS configuration with 4 parallel jobs appears to be a good balance for these projects.
</details>
Figure 5. Impact of number of jobs for make -j (left) and cargo build -j (right) with 4 available CPUs.
We found that the impact of gVisor (ES+) can be lessened by using parallelized builds, e.g., passing the -j argument to make. Figure 5 shows that ideal number is close to the number of available CPUs. In our case: 4. And while increasing numbers past this point is fine for host-based executions, it has negative impact for ES+. See Table 6 – 7 in Appendix D for more detailed measurements.
Finally, we build our complex targets clang and kernel on the larger machine where the TEE is assigned 16 vCPUs and 64 GiB. The larger memory allocation for the TEE increases the Start EIF duration from 29.5 s to 46.4 s compared to the smaller instance. Figure 6 shows that there is also a pronounced impact on the build duration. For example, clang ’s build time increased from 54 minutes (HS) to 63 minutes (ES, +18%) or 79 minutes (ES+, +48%).
For our overall overhead numbers we build all nine small targets and the two large targets back-back. With the baseline configuration HS this takes 1h22m. For A-Bs this increases to 1h34m (ES, +14%) and 2h14m (ES+, +62%). These numbers exclude the average start and boot overhead of 42.1s.
<details>
<summary>x6.png Details</summary>

### Visual Description
## [Chart Type]: Comparative Box Plots of Build Durations
### Overview
The image displays three separate box plots arranged horizontally, comparing the build duration (in seconds) for different software components under various configurations. The plots share a common x-axis category set but have different y-axis scales. The overall visual suggests an analysis of how build times vary across compiler types and optimization levels.
### Components/Axes
**Common Elements:**
* **X-axis Categories (All Plots):** Five discrete categories labeled: `H`, `HS`, `E`, `ES`, `ES+`. These likely represent different build configurations or optimization levels.
* **Y-axis Label (Leftmost Plot):** "Build duration (s)". This label applies to all three plots.
* **Plot Titles (Top of each plot):**
* Left Plot: `Clang (18.1.3)`
* Middle Plot: `Kernel (6.8.0, gcc)`
* Right Plot: `Kernel (6.8.0, clang)`
* **Visual Encoding:** Each category is represented by a horizontal box plot (a thick central line with thinner lines extending left and right, likely representing median and range/quartiles). All plots use the same dark gray color.
**Individual Plot Axes:**
1. **Left Plot (Clang 18.1.3):**
* **Y-axis Scale:** Linear, from 0 to over 4000. Major tick marks at `0`, `2000`, `4000`.
2. **Middle Plot (Kernel 6.8.0, gcc):**
* **Y-axis Scale:** Linear, from 0 to 600. Major tick marks at `0`, `200`, `400`, `600`.
3. **Right Plot (Kernel 6.8.0, clang):**
* **Y-axis Scale:** Linear, from 0 to 800. Major tick marks at `0`, `200`, `400`, `600`, `800`.
### Detailed Analysis
**Trend Verification & Data Points (Approximate Values):**
* **Left Plot - Clang (18.1.3):**
* **Trend:** Build duration shows a clear, stepwise increasing trend from category `H` to `ES+`.
* **Data Points (Median approx.):**
* `H`: ~2800 s
* `HS`: ~3200 s
* `E`: ~3300 s
* `ES`: ~3800 s
* `ES+`: ~4800 s (This is the highest value in the entire image).
* **Middle Plot - Kernel (6.8.0, gcc):**
* **Trend:** Build duration is relatively flat for the first four categories (`H` to `ES`), with a sharp, significant increase for `ES+`.
* **Data Points (Median approx.):**
* `H`: ~240 s
* `HS`: ~280 s
* `E`: ~250 s
* `ES`: ~280 s
* `ES+`: ~540 s
* **Right Plot - Kernel (6.8.0, clang):**
* **Trend:** Similar to the middle plot, showing a gradual, slight increase from `H` to `ES`, followed by a large jump for `ES+`.
* **Data Points (Median approx.):**
* `H`: ~410 s
* `HS`: ~420 s
* `E`: ~450 s
* `ES`: ~440 s
* `ES+`: ~740 s
### Key Observations
1. **Dominant Outlier:** The `ES+` configuration results in a dramatically higher build duration across all three scenarios compared to the other four configurations.
2. **Scale Disparity:** The absolute build times for the `Clang (18.1.3)` compiler (left plot) are an order of magnitude higher (thousands of seconds) than for the `Kernel` builds (hundreds of seconds).
3. **Compiler Comparison for Kernel:** When building the same Kernel (6.8.0), using `clang` (right plot) results in consistently longer build times than using `gcc` (middle plot) for all configurations. The difference is approximately 170-200 seconds for the `H` through `ES` categories.
4. **Configuration Sensitivity:** The `Clang` compiler's build time appears more sensitive to configuration changes, showing a steady increase from `H` to `ES+`. The `Kernel` builds are less sensitive until the `ES+` configuration is applied.
### Interpretation
This data visualizes the performance impact of different build configurations (`H`, `HS`, `E`, `ES`, `ES+`) on compilation time. The `ES+` configuration is a clear performance bottleneck, incurring a severe time penalty. This suggests `ES+` enables significantly more intensive processing (e.g., deeper optimizations, extensive instrumentation, or additional validation steps).
The comparison between the middle and right plots isolates the effect of the compiler (`gcc` vs. `clang`) on building the same Linux Kernel version (6.8.0). `Clang` is consistently slower, which could be due to differences in compiler architecture, default optimization levels, or the maturity of the kernel's build system support for `clang` at the time of this test.
The leftmost plot shows that building the `Clang` compiler itself (version 18.1.3) is a much more time-consuming task than building the kernel, which is expected given the complexity of a modern compiler codebase. The steady increase in its build time with configuration changes implies that each successive configuration (`H` -> `HS` -> `E` -> `ES` -> `ES+`) adds incremental, compounding work to the compiler's own build process.
**In summary, the key takeaway is the disproportionate cost of the `ES+` configuration, and the secondary observation of `clang`'s slower performance compared to `gcc` for kernel builds.**
</details>
Figure 6. The complex targets clang and kernel are additionally built without sandboxes on the host H and enclave E.
## 5. Formal verification using Tamarin
<details>
<summary>x7.png Details</summary>

### Visual Description
## Sequence Diagram: Secure Build and Attestation Protocol
### Overview
This image is a sequence diagram illustrating a multi-party protocol for securely building and attesting to software artifacts. It depicts the message flow between seven distinct entities, categorized into trusted, adversary, and untrusted execution states. The protocol involves committing code, initializing a secure build environment, performing the build, generating an attestation, logging the result, and finally verifying the artifact.
### Components/Axes
**Participants (Vertical Lifelines, Left to Right):**
* **A (Artifact Author):** The entity that initiates the process by committing code.
* **B (Verifier):** The entity that ultimately verifies the final artifact and its attestation.
* **C (RHP):** An intermediary component (likely a "Release Handling Platform" or similar).
* **D (Build Server):** The server that orchestrates the build process.
* **E (Enclave):** A secure, isolated execution environment (e.g., a TEE).
* **F (Sandbox):** The environment where the actual build execution occurs.
* **G (Log):** A logging service for recording the attestation.
**Legend (Right Side):**
* **Red Dashed Line (---):** Adversary Network
* **Black Solid Line (—):** Trusted Network
* **Red Dotted Line (······):** Untrusted Execution State
* **Vertical Red Dotted Line:** Labeled "untrusted state," positioned between the Enclave (E) and Sandbox (F) lifelines, extending vertically through the diagram.
### Detailed Analysis
The protocol proceeds through 11 numbered steps. The flow and message types are as follows:
1. **(1) `CommitA(code)`**
* **From:** A (Artifact Author)
* **To:** C (RHP)
* **Line Style:** Black Solid (Trusted Network)
* **Description:** The author commits source code to the RHP.
2. **(2) `InitImage(pcr0)`**
* **From:** D (Build Server)
* **To:** E (Enclave)
* **Line Style:** Red Dashed (Adversary Network)
* **Description:** The Build Server sends an initialization command to the Enclave, referencing a Platform Configuration Register (`pcr0`), which is a secure measurement of the enclave's initial state.
3. **(3) `InitBuild(code)`**
* **From:** C (RHP)
* **To:** D (Build Server)
* **Line Style:** Red Dashed (Adversary Network)
* **Description:** The RHP instructs the Build Server to start the build process with the committed code.
4. **(3) `InitBuild(code)`** (Repeated)
* **From:** D (Build Server)
* **To:** E (Enclave)
* **Line Style:** Red Dashed (Adversary Network)
* **Description:** The Build Server forwards the build initialization to the Enclave.
5. **(3) `InitBuild(code)`** (Repeated)
* **From:** E (Enclave)
* **To:** F (Sandbox)
* **Line Style:** Red Dashed (Adversary Network)
* **Description:** The Enclave forwards the build initialization to the Sandbox. This step crosses the vertical "untrusted state" boundary.
6. **(4) `VerifyCommit(h(code))`**
* **From/To:** Self-loop on E (Enclave)
* **Line Style:** Green Solid Arrow (Not in legend, but visually distinct)
* **Description:** The Enclave performs an internal verification of the code's hash (`h(code)`).
7. **(5) `SecureCommit(h(code))`**
* **From:** E (Enclave)
* **To:** D (Build Server)
* **Line Style:** Black Solid (Trusted Network)
* **Description:** The Enclave securely sends the verified code hash back to the Build Server.
8. **(6) `Build(code)`**
* **From/To:** Self-loop on F (Sandbox)
* **Line Style:** Black Solid Arrow
* **Description:** The Sandbox executes the build process on the code.
9. **(7) `SendHash(h(artifact))`**
* **From:** F (Sandbox)
* **To:** E (Enclave)
* **Line Style:** Red Dashed (Adversary Network)
* **Description:** The Sandbox sends the hash of the resulting build artifact (`h(artifact)`) back to the Enclave. This step crosses the "untrusted state" boundary.
10. **(8) `Attestation(commit, h(artifact), pcr0)`**
* **From:** E (Enclave)
* **To:** D (Build Server)
* **Line Style:** Red Dashed (Adversary Network)
* **Description:** The Enclave generates and sends a formal attestation. This attestation binds together: the original commit identifier, the hash of the final artifact, and the initial secure measurement (`pcr0`). The parameter `pcr0` is highlighted in red text.
11. **(9) `LogEntry(h(<commit, h(artifact), at>))`**
* **From:** D (Build Server)
* **To:** G (Log)
* **Line Style:** Red Dashed (Adversary Network)
* **Description:** The Build Server logs a hash of the attestation data (the commit, artifact hash, and attestation `at` itself) to the immutable Log service.
12. **(10) `Get(artifact, at, ip)`**
* **From:** D (Build Server)
* **To:** B (Verifier)
* **Line Style:** Black Solid (Trusted Network)
* **Description:** The Build Server delivers the final artifact, its attestation (`at`), and presumably an identity/proof (`ip`) to the Verifier.
13. **(11) `Verify(ip, pcr0)`**
* **From/To:** Self-loop on B (Verifier)
* **Line Style:** Green Solid Arrow
* **Description:** The Verifier performs the final check, validating the provided proof (`ip`) against the initial enclave measurement (`pcr0`) that was included in the attestation.
### Key Observations
1. **Network Trust Boundaries:** The diagram meticulously distinguishes between trusted (solid black) and adversary-controlled (dashed red) network paths. Notably, the initial `InitImage` and all messages involving the Sandbox (F) traverse the adversary network.
2. **Untrusted Execution State:** A critical architectural boundary is marked by the vertical red dotted line. The Sandbox (F), where the build runs, is explicitly placed within an "untrusted state," while the Enclave (E) is outside it. This implies the build environment itself is not trusted, but its output is verified by the trusted enclave.
3. **Verification Points:** There are two key internal verification steps (green arrows): one by the Enclave (E) on the input code hash, and one by the Verifier (B) on the final attestation and proof.
4. **Attestation Composition:** The attestation (step 8) is the core trust artifact, cryptographically linking the initial state (`pcr0`), the input (commit), and the output (`h(artifact)`).
5. **Logging for Auditability:** The use of a Log service (G) creates an immutable record of the attestation, enabling independent audit and verification later.
### Interpretation
This diagram details a **trusted execution environment (TEE) based secure build pipeline**. The core problem it solves is: "How can we trust the output of a build process (a software artifact) when the build server and environment might be compromised?"
The protocol's logic is as follows:
1. **Isolate Trust:** The only components that must be inherently trusted are the **Enclave (E)** and the **Verifier (B)**. The Build Server (D), RHP (C), and especially the Sandbox (F) are treated as potentially adversarial.
2. **Establish a Root of Trust:** The process begins by measuring the Enclave's initial state (`pcr0`). This measurement becomes the root of trust for the entire chain.
3. **Verify Inputs:** Before building, the Enclave verifies the hash of the source code it receives (`h(code)`), ensuring no tampering occurred on the untrusted network path from the RHP.
4. **Execute in Distrust:** The actual build runs in an untrusted Sandbox. This is acceptable because the Enclave does not trust the Sandbox's execution; it only cares about verifiably measuring its output.
5. **Bind Input to Output:** The Enclave creates an attestation that cryptographically binds the initial trusted state (`pcr0`), the verified input (commit), and the hash of the output artifact (`h(artifact)`). This attestation is a signed statement from the trusted Enclave saying, "I started in a known-good state, I received this specific code, and the build process produced this specific artifact."
6. **Enable External Verification:** The final Verifier (B) can check the attestation. By verifying the signature and confirming that the `pcr0` in the attestation matches the expected value for a genuine Enclave, it can trust that the artifact (`h(artifact)`) is the legitimate result of building the claimed code (`commit`), even though the build itself happened on an untrusted machine.
**Notable Anomaly/Design Choice:** The `InitImage(pcr0)` message (step 2) is sent over the adversary network. This suggests that while the *value* of `pcr0` is public or can be intercepted, its integrity is not compromised because `pcr0` is a measurement generated *within* the secure hardware of the Enclave itself. An adversary cannot forge a valid `pcr0` for a genuine Enclave running the correct code. The trust derives from the hardware's ability to generate and sign this measurement, not from the secrecy of its transmission.
</details>
Figure 7. Protocol flow overview of the formal model, illustrating the interactions and data exchanges between system components and adversary channels.
We use Tamarin (Basin, David and Cremers, Cas and Dreier, Jannik and Meier, Simon and Sasse, Ralf and Schmidt, Benedikt, 2025), a security protocol verification tool, to formally model and verify the underlying protocol of A-Bs. In Tamarin, facts represent states of a party involved in a protocol. Thus, we can use facts to describe how the components of our system can interact with each other. Tamarin allows two types of facts: a linear fact that can be consumed only once as it contributes to the system state, and a persistent fact that can be consumed multiple times. A fact in Tamarin is written in the form of $F(t_{1}..t_{n})$ , where $F$ is the name of the fact and $t_{i}$ the value of the current state. We also use some already built-in facts in Tamarin, like $Fr(x)$ , $In(..)$ , and $Out(..)$ . The $Fr(x)$ fact generates a fresh random value and the $In(..)$ and $Out(..)$ facts are used to receive and send something from and to an adversary-controlled network, respectively.
Tamarin uses multiset rewriting rules (MSR) to describe state transitions. A MSR consists of a name, a left-hand side, an optional middle part, and a right-hand side. The left-hand side defines the facts that needs to be present in order to initiate the MSR. The middle part, also called action fact, is used to label the specific transition and makes it available for the verification step. The right-hand side describes the state(s) of the outcome.
Finally, we define the security properties to be verified. Tamarin uses lemmas to verify both the expected behavior of the protocol and the results of state transitions based on the given action facts. Considering the action facts including an expected time-dependent relation Tamarin derives traces using first-order logic.
### 5.1. Security properties
This section outlines various attack categories on security properties used to verify source-to-binary correspondence, including the authenticity of the repository. These attack categories are based on our threat model described in Section 3.2 and we link each category with the respective threat(s) alongside a reference for clarity. The underlying trust assumptions of our threat model (§ 3.2.1) also apply for the formal model. We model the security properties as formulas in a first-order logic using Tamarin lemmas. To verify both protocol behavior and data integrity we utilize action facts in the form $F(x_{1}..x_{n})\#i$ where $F$ represents the name of the action fact, $x_{1..n}$ the data, and $\#i$ the time variable for the execution. Each subsequent paragraph describes the respective attack category and consists of two proofs: one demonstrating that the specific security property can be successfully compromised when not utilizing A-Bs, and another to ensure that there exists no trace where an adversary would be successful when using A-Bs. We use the function $h(..)$ , which represents a hash function and variables $c,ct,a,at,ip$ representing the data: c ode, c ommi t hash, a rtifact, at testation, and i nclusion p roof. The full lemmas of the security properties described below as well as an example illustration of a detected attack by Tamarin are provided in the Appendix C for reference.
Code manipulation (T1, T2, T6)
This attack category examines whether an adversary can successfully manipulate code during the build process. Specifically, this includes compromising code on the build server, attacking shared infrastructure, and considering hardware attacks (assuming the TEE to be trustworthy). Our formal verification begins with proofing that Tamarin can find a trace where an adversary can compromise code $c$ when specific verification controls, used to verify the commit hash $ct$ , are not incorporated. Specifically, this lemma proofs that $\exists\ c,ct:\neg(h(c)=ct)$ . For the second proof of this attack category, which includes the verification step, Tamarin does not find any trace where an adversary is able to manipulate code without detection. This proof verifies that $\forall\ c,ct:h(c)=ct$ .
Build asset manipulation (T1, T2, T3, T6)
The attack category examines whether an adversary can successfully manipulate a build asset (e.g., the artifact) including potentially malicious libraries side-loaded from external sources. Tamarin is able to find a trace where an adversary can successfully compromise a build asset $a$ when specific verification controls, used to verify the inclusion proof $ip$ , are not incorporated. Specifically, this lemma proves that $\exists\ c,ct,at,ip:\neg(h(<ct,h(c),h(c)>)=ip)$ . In case of incorporating the verification of the inclusion proof, provided by the transparency log, based on code sent via the adversary network and the attestation $at$ provide by the TEE, Tamarin does not find a trace where an adversary can manipulate a build asset without detection. Specifically, this lemma proves that $\forall\ c,ct,a,at,ip:h(c)=ct\wedge h(<ct,h(a),at>)=ip$ .
Build infrastructure manipulation (T1, T2, T6)
This attack category focuses on successful attacks in which an adversary is able to compromise the infrastructure environment, i.e. the enclave image. To model this scenario, we transfer the build image through the adversary network so that the adversary can modify it. This analogously covers physical attacks against the machine running the image in an enclave. Thus, our first lemma in this category verifies whether an adversary can provide an attestation document $at$ based on a compromised build image without using the trusted PCR value $p$ to verify the attestation. Specifically, it proves that $\exists\ c,ct,a,p,at:\neg(<c,h(a),p>)=at)$ . However, if we include the proper verification in our model, Tamarin does not find any trace where an adversary can use a manipulated build image without detection. The respective proof shows that $\forall\ c,ct,a,p,at:(<c,h(a),p>)=at$ .
Repository Spoofing (T4)
The last attack category is particularly relevant for spoofing attacks with regards to the repository. An adversary might be able to spoof the repository and to create a valid inclusion proof for a particular commit hash of this repository. In this case, a verifier trying to audit the spoofed repository would get a valid inclusion proof. The first lemma, used to verify whether an adversary can successfully spoof the repository when not verifying the inclusion proof shows that $\exists\ c,ct,a,at,ip:\neg(h(<h(c),h(a),at>)=ip)$ . To prevent such spoofing attacks, the artifact author also needs to verify the corresponding inclusion proof according to the trustworthy reference $r$ . Thus, the second lemma proves that $\forall\ c,ct,a,at,ip,r:h(c)=ct\wedge r=ip$ .
## 6. Related work
The challenge of building software artifacts and distributing them in a trustworthy manner has been known for more than 50 years. A report on the Multics system by the US Air Force from 1974, was one of the first to present the idea of a compiler trap door (Karger and Schell, 2002). Ken Thompson popularized the theme of “Trusting Trust” in his Turing Award Lecture in 1984—stating that no amount of source code scrutiny can protect against malicious build processes (Thompson, 1984). In his examples he discusses the implication of a malicious compiler that can introduce a vulnerability in a targeted output binary and preserves this behavior even when it compiles itself from clean source code. David Wheeler suggests Diverse Double-Compiling (DDC) as a practical solution where one uses a trusted compiler to verify the truthful recompilation of the main compiler (Wheeler, 2005). However, this leaves open the question on how to arrive at such a trusted compiler as well as to ensure a trustworthy environment to run the proposed steps in. Projects like Bootstrappable Builds discuss approaches to build modern systems from scratch using minimal pre-compiled inputs (project, 2024b).
The trusted compiler issue can be addressed by having R-Bs and relying either on diverse environments under a at-least-one-trusted assumption or trusting the local setup. The inherent challenges are discussed in academic literature for both individual tools and the overall environment (de Carné de Carnavalet and Mannan, 2014; Lamb and Zacchiroli, 2021). More papers include industry perspectives on business adoption (Butler et al., 2023), experience reports for large commercial systems (Shi et al., 2021), and importance and challenges as perceived by developers (Fourné et al., 2023). In addition, there has been work aiming at making build environments and tools more deterministic (Navarro Leija et al., 2020; Xiong et al., 2022; Glukhova et al., 2017).
Similar to our approach of using Confidential Computing (CC) for providing integrity, Russinovich et al. introduce the idea of Confidential Computing Proofs (CCP) as a more scalable alternative to Zero Knowledge Proofs which rely on heavy and slow cryptography (Russinovich et al., 2024). A-Bs can be seen as a form of CCP that is persisted using a transparency log. Meng et al. propose the use of TPMs in software aggregation to reduce the size of hard-coded lists of trusted binary artifacts (Meng et al., 2009), but their work lacks a security model and does not generalize to cloud-based CI/CD with untrusted build processes. Others also identified the challenges and opportunities of Confidential Computing as a Service (CCaaS) and our deployment model is inspired by the work by Chen et al. (Chen et al., 2023). With the advances of AI/ML, CC is used for confidential interference where AI models are executed within TEEs (Mohan et al., 2024; Russinovich, 2024).
Trust of pre-built dependencies is key for supply chain security and software updates. The framework Supply-chain Levels for Software Artifacts (SLSA) provides helpful threat-modeling and taxonomy to discuss guarantees provided by different systems (Foundation, 2025). Both R-Bs and A-Bs could be adopted as a new level L4 (see Table 2). Frameworks like SLSA become particularly valuable when integrated with codified descriptions such as the in-toto standard (Foundation, 2024) CHAINIAC demonstrates how to transparently ship updates using skipchains and verified builds (Nikitin et al., 2017).
Table 2. The existing SLSA levels L0–L3 adapted from (Foundation, 2025) and possible new L4 levels for A-Bs and R-Bs.
| L4 L4 | Attestable build $\rightharpoonup$ Attested trust in builder Reproducible build |
| --- | --- |
| $\rightharpoonup$ Verifiable trust in builder | |
| L3 | Hardened build platform |
| $\rightharpoonup$ Tampering during the build | |
| L2 | Signed provenance from a hosted build platform |
| $\rightharpoonup$ Tampering after the build | |
| L1 | Provenance showing how the package was built |
| $\rightharpoonup$ Mistakes, documentation | |
| L0 | n/a |
Sigstore provides an ecosystem (Newman et al., 2022) to sign and verify artifacts. The authentication certificate together with the artifact hash and the signature is then logged in a transparency log for later verification and allows to later verify a downloaded artifact. Both, A-B and the Sigstore project incorporate a transparency log for end-to-end verification. In SigStore it makes the signature process verifiable, while we use the transparency log to store metadata about the attested build.
Hardware-based security solutions provide a strong trust anchor, especially when interacting with hardware operated by others. However, they are not infallible as attacks on Confidential Computing technology have shown. As the first broadly-available solution, Intel SGX has received a lot of attention with attacks ranging from side-channel attacks (Götzfried et al., 2017; Lee et al., 2017) to active attacks (Chen et al., 2019; Murdock et al., 2020). The survey by Nilsson et al. summarizes most of them (Nilsson et al., 2020). As a process-level isolation technique, SGX is an easier target than the newer VM-based designs where exclusive CPU allocation makes them more resistant to side-channels. Nevertheless, researchers have attacked some of its guarantees through side-channels (Li et al., 2021), active attacks (Morbitzer et al., 2018; Schlüter et al., 2024), and memory aliasing (De Meulemeester et al., 2025).
## 7. Deployment consideration
Going beyond executable binaries
In this paper we focus on executable binary artifacts that are given to verifiers, e.g., a user downloading new software from the Internet. However, we can also attest other build process outputs. One natural area are supply-chains of software libraries. In such a system, each dependency is built in an attestable manner and the downstream builders verify each included dependency. Since this verification step is part of the attested build process, trust spreads transitively. A-Bs can also attest non-binary artifacts. Examples are the outcome of a vulnerability scanning program, i.e. this artifact is secure, or accuracy scores of a benchmark that is run in CI against the built artifact, i.e. this artifact meets a certain standard. Another compelling application of the attestable build paradigm is its use as part of an issuing authority, e.g., an SSL provider who needs to perform certain checks while creating a new certificate, where trust is an essential aspect.
Integrating with existing CI/CD systems.
Our prototype already integrates with the GitHub Actions CI/CD product using workflow files (.yml). We found that the required changes are typically less than 10 lines and Appendix B shows a side-by-side comparison of the changes to a typical workflow file. Overall, the developer experience remains the same. Figure 9 in Appendix A shows a web screenshot during our evaluation. Attestable Builds can be provided by a third-party providing audited base images and run on untrusted CSPs.
Mitigating performance impact
In our evaluation, A-Bs incur a large start-up overhead. However, in practice this can be mitigated from the user by maintaining a number of “pre-warmed” enclaves that are booted, but have not yet fetched any source code. Additionally, as EC2 instances can host a mix of multiple enclaves of various size—given sufficient vCPU and RAM resources—the overall costs can remain low. A load balancer can then redirect build requests to the most suitable ready instance.
Extending the log
In this paper, our transparency log contains entries that link source code snapshots and binary artifacts. However, in a production system these logs can be extended with various types of entries that more holistically capture the security of a given artifact. For example, auditors might provide SourceAudit entries signed by their private key to vouch for a given code snapshot and maybe even link them to a set of audit standards published by regulators. Software and hardware vendors might publish RevocationNotices when new vulnerabilities are discovered. Based on these, the artifact authors can then ask the independent log monitors to regularly provide compact proofs that attest to the fact that (a) an artifact was built from a given code snapshot, (b) that code snapshot was audited to an accepted standard, and (c) that there are no revocation notices affecting this version. The verifier then only needs to check threshold many such up-to-date proofs instead of having to inspect the entire log themselves.
### 7.1. Case studies
<details>
<summary>x8.png Details</summary>

### Visual Description
## Diagram: Software Packaging Workflow
### Overview
The image is a black-and-white technical diagram illustrating a linear workflow for creating a Debian package (`.deb`) from source code. It depicts a sequence of stages involving different entities and file formats, connected by directional arrows indicating the flow of the process.
### Components/Axes
The diagram consists of five primary components arranged horizontally from left to right, with one component positioned below the main flow.
1. **Source (Top-Left):** Represented by an icon of a document with a folded corner and the code symbol `</>`. The label "Source" is positioned above the icon.
2. **Maintainer (Bottom-Left):** Represented by an icon of a laptop computer. The label "Maintainer" is positioned to the right of the laptop icon.
3. **.tar.gz (Center):** Represented by an icon of a simple 3D box or cube. The label ".tar.gz" is positioned above the icon.
4. **Packager (Center-Right):** Represented by a combined icon of a gear (cog) and a cloud. The label "Packager" is positioned below the icon.
5. **.deb (Far-Right):** Represented by an icon of a solid, dark 3D cube. The label ".deb" is positioned above the icon.
**Flow Connections (Arrows):**
* An arrow originates from the "Source" icon, travels right, then down, pointing into the top of the "Maintainer" laptop icon.
* An arrow originates from the "Maintainer" laptop icon, travels up, then right, pointing into the left side of the ".tar.gz" box icon.
* An arrow points directly from the right side of the ".tar.gz" box icon to the left side of the "Packager" gear/cloud icon.
* An arrow points directly from the right side of the "Packager" gear/cloud icon to the left side of the ".deb" cube icon.
### Detailed Analysis
The diagram outlines a specific, sequential technical process:
1. **Stage 1 - Source Code:** The process begins with "Source" code, symbolized by the `</>` document.
2. **Stage 2 - Human Intervention:** The source code is acted upon by a "Maintainer," represented by the laptop. This implies a human developer or package maintainer performs manual preparation, configuration, or modification steps.
3. **Stage 3 - Archiving:** The output of the maintainer's work is a compressed tarball, denoted by the ".tar.gz" label and box icon. This is a standard format for distributing source code archives on Unix-like systems.
4. **Stage 4 - Automated Packaging:** The `.tar.gz` archive is processed by a "Packager," symbolized by the gear (automation/tool) and cloud (potentially indicating a build service or repository). This stage represents automated build scripts or tools (like `dpkg-buildpackage`) that compile the source and organize files according to Debian policy.
5. **Stage 5 - Final Artifact:** The final output is a Debian binary package, represented by the solid ".deb" cube icon. This is the installable package file.
### Key Observations
* **Role Distinction:** The diagram clearly separates the human role ("Maintainer") from the automated tool role ("Packager").
* **File Format Specificity:** It explicitly names the intermediate (`.tar.gz`) and final (`.deb`) file formats, which are specific to the Debian/Ubuntu software ecosystem.
* **Linear, Unidirectional Flow:** The process is shown as a one-way pipeline with no feedback loops or decision points, suggesting a simplified, idealized view of the packaging process.
* **Iconography:** The icons are symbolic rather than literal. The "Packager" cloud/gear combo is particularly abstract, representing a process rather than a single physical object.
### Interpretation
This diagram serves as a high-level conceptual model for the **Debian package creation pipeline**. It communicates the fundamental transformation of raw source code into a distributable, installable binary package.
* **What it demonstrates:** It illustrates the division of labor between human curation (the Maintainer who prepares the source, writes rules, and ensures policy compliance) and machine automation (the Packager that executes the build in a controlled environment). The flow emphasizes that the maintainer's output is not the final package, but a prepared source archive that feeds into an automated build system.
* **Relationships:** The arrows define a strict dependency chain. The `.deb` file cannot be created without the Packager, which requires the `.tar.gz` archive, which in turn depends on the work of the Maintainer using the original Source. Each component is a necessary precursor to the next.
* **Notable Context:** This workflow is foundational to Linux distribution maintenance. The "Maintainer" is a key role in open-source projects, responsible for the packaging and long-term support of software within a distribution like Debian or Ubuntu. The "Packager" likely refers to tools like `pbuilder`, `sbuild`, or CI/CD systems that ensure clean, reproducible builds. The diagram abstracts away complexities like dependency resolution, patching, and configuration, focusing instead on the core transformation of artifacts.
</details>
Figure 8. Illustration of the XZ build chain.
A key aspect of the XZ incident (CVE-2024-3094) (Lins et al., 2024) was that the adversary added an additional build asset build-to-host.m4 to the tarball used by the packager to build the final artifact (see Figure 8). Having some pre-generated files (e.g., configure script) is common for projects utilizing Autoconf to make the build process easier for others. However, as these build assets are not part of the repository, it is difficult to verify whether these assets have been generated trustworthily. Additionally, the concept of R-Bs might not apply as the resulting artifact likely differs when built on another build host. We believe that A-Bs can offer an additional layer of transparency, making it verifiable that the generated build assets were created in a trustworthy environment based on a specific source code snapshot. Thus, in case of using A-Bs with XZ, the adversary would be forced to use a repository containing all required source code, including the covert build-to-host.m4 file, to create the tarball that is finally used by the packager.
The SolarWinds hack (Zetter, 2023) has a large impact after adversaries successfully compromised a critical supply-chain by implanting a backdoor in a critical software package. The defining aspect of this episode was that the adversaries did not modify the source code in the repository, but were able to compromise the build infrastructure (T1) in a covert manner. Specifically, SUNSPOT was used to inject a SUNBURST backdoor into the final artifact by replacing the corresponding source file during the build process (Team, 2021). If A-Bs were used, the change in the PCR values or a failing attestation would have indicated that the build image was modified.
These deployment considerations and potential mitigation for such supply-chain attacks are particularly important for audited, but closed-source firmware. A practical attack demonstration where the authors explain how to engineer a backdoored bitcoin wallet highlights this issue for high-assurance use-cases (Scott and Andersen, 2024). We believe that A-Bs can help mitigate such attacks, as the build step itself runs within a trusted and verifiable environment, thus preventing persistent and covert compromise.
## 8. Conclusion
We presented Attestable Builds (A-Bs) as a new paradigm to provide strong source-to-binary correspondence in software artifacts. Our approach ensures that a third-party can verify that a specific source-code snapshot used to build a given artifact. It takes into account the modern reality of software development which often relies on a large set of third-parties and cloud-hosted services. We demonstrated this by integrating our prototype with a popular CI/CD framework as part of our evaluation.
Our prototype builds existing projects with no source code changes, and only minimal changes to existing build configurations. We show that it has acceptable overhead for small projects and can also take on notoriously complex projects such as LLVM clang. More interesting use-cases are possible, such as attesting non-binary artifacts and building composite systems which also support reproducible builds. Importantly, A-Bs can be pragmatically adopted for difficult gaps in R-B projects as well as an off-the-shelf solution for migrating entire projects.
## Acknowledgments
We thank Jenny Blessing, Adrien Ghosn, Alberto Sonnino, and Tom Sutcliffe for the helpful feedback. All errors remain our own. Daniel is supported by Nokia Bell Labs. This work has been carried out within the scope of Digidow, the Christian Doppler Laboratory for Private Digital Authentication in the Physical World and has partially been supported by the LIT Secure and Correct Systems Lab. We gratefully acknowledge financial support by the Austrian Federal Ministry of Labour and Economy, the National Foundation for Research, Technology and Development, the Christian Doppler Research Association, 3 Banken IT GmbH, ekey biometric systems GmbH, Kepler Universitätsklinikum GmbH, NXP Semiconductors Austria GmbH & Co KG, Österreichische Staatsdruckerei GmbH, and the State of Upper Austria.
## Availability
Our prototype, evaluation, and results are available in our repository under an MIT license: https://github.com/lambdapioneer/attestable-builds. The source code snapshots and build configurations of third-party projects that we used in our evaluation are available in a secondary repository under their own respective licenses: https://github.com/lambdapioneer/ab-samples.
## References
- (1)
- Basin, David and Cremers, Cas and Dreier, Jannik and Meier, Simon and Sasse, Ralf and Schmidt, Benedikt (2025) Basin, David and Cremers, Cas and Dreier, Jannik and Meier, Simon and Sasse, Ralf and Schmidt, Benedikt. 2025. Tamarin Prover. https://tamarin-prover.com/. Last accessed January 2025.
- Biffle (2024) Cliff L. Biffle. 2024. The Typestate Pattern in Rust. http://cliffle.com/blog/rust-typestate/. Last accessed December 2024.
- Butler et al. (2023) Simon Butler, Jonas Gamalielsson, Björn Lundell, Christoffer Brax, Anders Mattsson, Tomas Gustavsson, Jonas Feist, Bengt Kvarnström, and Erik Lönroth. 2023. On business adoption and use of reproducible builds for open and closed source software. Software Quality Journal 31, 3 (2023), 687–719.
- Castes et al. (2023) Charly Castes, Adrien Ghosn, Neelu S Kalani, Yuchen Qian, Marios Kogias, Mathias Payer, and Edouard Bugnion. 2023. Creating Trust by Abolishing Hierarchies. In Proceedings of the 19th Workshop on Hot Topics in Operating Systems. 231–238.
- Chen et al. (2019) Guoxing Chen, Sanchuan Chen, Yuan Xiao, Yinqian Zhang, Zhiqiang Lin, and Ten H Lai. 2019. SgxPpectre: Stealing Intel secrets from SGX enclaves via speculative execution. In 2019 IEEE European Symposium on Security and Privacy (EuroS&P). IEEE, 142–157.
- Chen et al. (2023) Hongbo Chen, Haobin Hiroki Chen, Mingshen Sun, Kang Li, Zhaofeng Chen, and XiaoFeng Wang. 2023. A verified confidential computing as a service framework for privacy preservation. In 32nd USENIX Security Symposium (USENIX Security 23). 4733–4750.
- community (2024) Mercurial community. 2024. Mercurial Homepage. https://www.mercurial-scm.org. Last accessed November 2024.
- Corporation (2024) Intel Corporation. 2024. Intel Trust Domain Extensions (Intel TDX). https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/overview.html. Last accessed November 2024.
- Costan (2016) Victor Costan. 2016. Intel SGX explained. IACR Cryptol, EPrint Arch (2016).
- Cybersecurity & Infrastructure Security Agency (2021) Cybersecurity & Infrastructure Security Agency. 2021. Emergenc Directive ED 21-01: Mitigate SolarWinds Orion Code Compromise.
- de Carné de Carnavalet and Mannan (2014) Xavier de Carné de Carnavalet and Mohammad Mannan. 2014. Challenges and implications of verifiable builds for security-critical open-source software. In Proceedings of the 30th Annual Computer Security Applications Conference. 16–25.
- De Meulemeester et al. (2025) Jesse De Meulemeester, Luca Wilke, David Oswald, Thomas Eisenbarth, Ingrid Verbauwhede, and Jo Van Bulck. 2025. BadRAM: Practical Memory Aliasing Attacks on Trusted Execution Environments. In 46th IEEE Symposium on Security and Privacy (S&P).
- Eijdenberg et al. (2015) Adam Eijdenberg, Ben Laurie, and Al Cutter. 2015. Verifiable data structures. Google Research, Tech. Rep (2015).
- et al. (2025) Holger Levsen et al. 2025. Overview of various statistics about reproducible builds. https://tests.reproducible-builds.org/debian/reproducible.html. Last accessed April 2025.
- Foundation (2024) The Linux Foundation. 2024. in-toto: A framework to secure the integrity of software supply chains. https://in-toto.io/. Last accessed November 2024.
- Foundation (2025) The Linux Foundation. 2025. Safeguarding artifact integrity across any software supply chain. https://slsa.dev/. Last accessed April 2025.
- Fourné et al. (2023) Marcel Fourné, Dominik Wermke, William Enck, Sascha Fahl, and Yasemin Acar. 2023. It’s like flossing your teeth: On the importance and challenges of reproducible builds for software supply chain security. In 2023 IEEE Symposium on Security and Privacy (S&P). IEEE, 1527–1544.
- Gevers (2023) Paul Gevers. 2023. Bits from the Release Team: Cambridge sprint update. https://lists.debian.org/debian-devel-announce/2023/12/msg00003.html. Last accessed April 2025.
- Glukhova et al. (2017) Maria Glukhova et al. 2017. Tools for ensuring reproducible builds for open-source software. (2017).
- Götzfried et al. (2017) Johannes Götzfried, Moritz Eckert, Sebastian Schinzel, and Tilo Müller. 2017. Cache attacks on Intel SGX. In Proceedings of the 10th European Workshop on Systems Security. 1–6.
- gVisor Authors (2025) The gVisor Authors. 2025. gVisor Homepage. https://gvisor.dev/. Last accessed January 2025.
- Harush (2025) Jossef Harush. 2025. Large Scale Campaign Created Fake GitHub Projects Clones with Fake Commit Added Malware. https://checkmarx.com/blog/large-scale-campaign-created-fake-github-projects-clones-with-fake-commit-added-malware/. Last accessed January 2025.
- Inc. (2024a) Advanced Micro Devices Inc. 2024a. AMD Secure Encrypted Virtualization (SEV). https://www.amd.com/en/developer/sev.html. Last accessed November 2024.
- Inc. (2024b) GitHub Inc. 2024b. GitHub Actions: automate your workflow from idea to production. https://github.com/features/actions. Last accessed November 2024.
- Inc. (2024c) GitHub Inc. 2024c. GitHub Homepage. https://github.com/. Last accessed November 2024.
- Inc. (2024d) GitLab Inc. 2024d. GitLab Homepage. https://about.gitlab.com/. Last accessed November 2024.
- Inc. (2024e) The NetBSD Foundation Inc. 2024e. NetBSD fully reproducible builds. https://blog.netbsd.org/tnf/entry/netbsd_fully_reproducible_builds. Last accessed November 2024.
- Karger and Schell (2002) Paul A Karger and Roger R Schell. 2002. Thirty years later: Lessons from the multics security evaluation. In 18th Annual Computer Security Applications Conference, 2002. Proceedings. IEEE, 119–126.
- Katz and Lindell (2007) Jonathan Katz and Yehuda Lindell. 2007. Introduction to modern cryptography: principles and protocols. Chapman and hall/CRC.
- Lamb and Zacchiroli (2021) Chris Lamb and Stefano Zacchiroli. 2021. Reproducible builds: Increasing the integrity of software supply chains. IEEE Software 39, 2 (2021), 62–70.
- Laurie (2014) Ben Laurie. 2014. Certificate transparency. Commun. ACM 57, 10 (2014), 40–46.
- Lee et al. (2017) Sangho Lee, Ming-Wei Shih, Prasun Gera, Taesoo Kim, Hyesoon Kim, and Marcus Peinado. 2017. Inferring fine-grained control flow inside SGX enclaves with branch shadowing. In 26th USENIX Security Symposium (USENIX Security 17). 557–574.
- Li et al. (2021) Mengyuan Li, Yinqian Zhang, Huibo Wang, Kang Li, and Yueqiang Cheng. 2021. CIPHERLEAKS: Breaking Constant-time Cryptography on AMD SEV via the Ciphertext Side Channel. In 30th USENIX Security Symposium (USENIX Security 21). 717–732.
- Lins et al. (2024) Mario Lins, René Mayrhofer, Michael Roland, Daniel Hofer, and Martin Schwaighofer. 2024. On the critical path to implant backdoors and the effectiveness of potential mitigation techniques: Early learnings from XZ. arXiv preprint arXiv:2404.08987 (2024).
- Ltd (2024) Atlassian Pty Ltd. 2024. Bitbucket – Git solution for teams using JIRA. https://bitbucket.org/product/. Last accessed November 2024.
- LWN.net (2025) LWN.net. 2025. Debian bookworm live images now fully reproducible. https://lwn.net/Articles/1015402/, Last accessed April 2025.
- Meng et al. (2009) Ce Meng, Yeping He, and Qian Zhang. 2009. Remote attestation for custom-built software. In 2009 International Conference on Networks Security, Wireless Communications and Trusted Computing, Vol. 2. IEEE, 374–377.
- Mohan et al. (2024) Apoorve Mohan, Mengmei Ye, Hubertus Franke, Mudhakar Srivatsa, Zhuoran Liu, and Nelson Mimura Gonzalez. 2024. Securing AI Inference in the Cloud: Is CPU-GPU Confidential Computing Ready?. In 2024 IEEE 17th International Conference on Cloud Computing (CLOUD). IEEE, 164–175.
- Morbitzer et al. (2018) Mathias Morbitzer, Manuel Huber, Julian Horsch, and Sascha Wessel. 2018. SEVered: Subverting AMD’s virtual machine encryption. In Proceedings of the 11th European Workshop on Systems Security. 1–6.
- Murdock et al. (2020) Kit Murdock, David Oswald, Flavio D Garcia, Jo Van Bulck, Daniel Gruss, and Frank Piessens. 2020. Plundervolt: Software-based fault injection attacks against Intel SGX. In 2020 IEEE Symposium on Security and Privacy (SP). IEEE, 1466–1482.
- Navarro Leija et al. (2020) Omar S Navarro Leija, Kelly Shiptoski, Ryan G Scott, Baojun Wang, Nicholas Renner, Ryan R Newton, and Joseph Devietti. 2020. Reproducible containers. In Proceedings of the Twenty-Fifth International Conference on Architectural Support for Programming Languages and Operating Systems. 167–182.
- Neupane et al. (2023) Shradha Neupane, Grant Holmes, Elizabeth Wyss, Drew Davidson, and Lorenzo De Carli. 2023. Beyond typosquatting: an in-depth look at package confusion. In 32nd USENIX Security Symposium (USENIX Security 23). 3439–3456.
- Newman et al. (2022) Zachary Newman, John Speed Meyers, and Santiago Torres-Arias. 2022. Sigstore: Software Signing for Everybody. In Proceedings of the 2022 ACM SIGSAC Conference on Computer and Communications Security (Los Angeles, CA, USA) (CCS ’22). Association for Computing Machinery, New York, NY, USA, 2353–2367. doi: 10.1145/3548606.3560596
- Nikitin et al. (2017) Kirill Nikitin, Eleftherios Kokoris-Kogias, Philipp Jovanovic, Nicolas Gailly, Linus Gasser, Ismail Khoffi, Justin Cappos, and Bryan Ford. 2017. CHAINIAC: Proactive Software-Update transparency via collectively signed skipchains and verified builds. In 26th USENIX Security Symposium (USENIX Security 17). 1271–1287.
- Nilsson et al. (2020) Alexander Nilsson, Pegah Nikbakht Bideh, and Joakim Brorsson. 2020. A survey of published attacks on Intel SGX. arXiv preprint arXiv:2006.13598 (2020).
- Perry and Project (2024) Mike Perry and The Tor Project. 2024. Deterministic Builds Part One: Cyberwar and Global Compromise. https://blog.torproject.org/deterministic-builds-part-one-cyberwar-and-global-compromise/. Last accessed November 2024.
- Pinto and Santos (2019) Sandro Pinto and Nuno Santos. 2019. Demystifying ARM TrustZone: A comprehensive survey. ACM computing surveys (CSUR) 51, 6 (2019), 1–36.
- Project (2024) Debian Project. 2024. Reproducible Builds. https://wiki.debian.org/ReproducibleBuilds/About. Last accessed November 2024.
- project (2024a) Jenkins project. 2024a. Jenkins Homepage. https://www.jenkins.io/. Last accessed November 2024.
- project (2024b) The Bootstrappable Builds project. 2024b. Bootstrappable Builds. https://bootstrappable.org/. Last accessed November 2024.
- Project (2024) The Chromium Project. 2024. Deterministic builds. https://chromium.googlesource.com/chromium/src/+/HEAD/docs/deterministic_builds.md. Last accessed November 2024.
- project (2024a) The Git project. 2024a. Git Homepage. https://git-scm.com. Last accessed November 2024.
- project (2024b) The Git project. 2024b. Git Tools Signing your work. https://git-scm.com/book/ms/v2/Git-Tools-Signing-Your-Work. Last accessed January 2025.
- Russinovich (2024) Mark Russinovich. 2024. Azure AI Confidential Inferencing: Technical Deep-Dive. https://techcommunity.microsoft.com/blog/azureconfidentialcomputingblog/azure-ai-confidential-inferencing-technical-deep-dive/4253150. Last accessed November 2024.
- Russinovich et al. (2024) Mark Russinovich, Cédric Fournet, Greg Zaverucha, Josh Benaloh, Brandon Murdoch, and Manuel Costa. 2024. Confidential Computing Proofs: An alternative to cryptographic zero-knowledge. Queue 22, 4 (2024), 73–100.
- Schlüter et al. (2024) Benedict Schlüter, Supraja Sridhara, Mark Kuhne, Andrin Bertschi, and Shweta Shinde. 2024. Heckler: Breaking Confidential VMs with Malicious Interrupts. In USENIX Security.
- Scott and Andersen (2024) Adam Scott and Sean Andersen. 2024. Engineering a backdoored bitcoin wallet. In 18th USENIX WOOT Conference on Offensive Technologies (WOOT 24). USENIX Association, Philadelphia, PA, 89–100. https://www.usenix.org/conference/woot24/presentation/scott
- Shi et al. (2021) Yong Shi, Mingzhi Wen, Filipe R Cogo, Boyuan Chen, and Zhen Ming Jiang. 2021. An experience report on producing verifiable builds for large-scale commercial systems. IEEE Transactions on Software Engineering 48, 9 (2021), 3361–3377.
- Simpson et al. (2019) Gary Simpson, Amy Nelson, Shiva Dasari, Ken Goldman, Nayna Jain, Jiewen Yao, Qin Long, Robert Hart, Ronald Aigner, and Dick Wilkins. 2019. TCG PC Client Specific Platform Firmware Profile Specification. Technical Report. Trusted Computing Group. Version 1.04, https://trustedcomputinggroup.org/resource/pc-client-specific-platform-firmware-profile-specification/. Last accessed November 2024.
- Skarlatos et al. (2019) Dimitrios Skarlatos, Mengjia Yan, Bhargava Gopireddy, Read Sprabery, Josep Torrellas, and Christopher W Fletcher. 2019. Microscope: Enabling microarchitectural replay attacks. In Proceedings of the 46th International Symposium on Computer Architecture. 318–331.
- Taylor et al. (2020) Matthew Taylor, Ruturaj Vaidya, Drew Davidson, Lorenzo De Carli, and Vaibhav Rastogi. 2020. Defending against package typosquatting. In Network and System Security: 14th International Conference, NSS 2020, Melbourne, VIC, Australia, November 25–27, 2020, Proceedings 14. Springer, 112–131.
- Team (2021) CrowdStrike Intelligence Team. 2021. SUNSPOT: An Implant in the Build Process. (2021). https://www.crowdstrike.com/en-us/blog/sunspot-malware-technical-analysis/. Last accessed January 2025.
- Thompson (1984) Ken Thompson. 1984. Reflections on trusting trust. Commun. ACM 27, 8 (1984), 761–763.
- Van Schaik et al. (2020) Stephan Van Schaik, Andrew Kwong, Daniel Genkin, and Yuval Yarom. 2020. SGAxe: How SGX fails in practice. https://sgaxe.com/files/SGAxe.pdf. Last accessed November 2024.
- web services (2024) Amazon web services. 2024. AWS Nitro Enclaves. https://aws.amazon.com/ec2/nitro/nitro-enclaves/. Last accessed December 2024.
- Wheeler (2005) David A Wheeler. 2005. Countering trusting trust through diverse double-compiling. In 21st Annual Computer Security Applications Conference (ACSAC’05). IEEE, 13–pp.
- Xiong et al. (2022) Jiawen Xiong, Yong Shi, Boyuan Chen, Filipe R Cogo, and Zhen Ming Jiang. 2022. Towards build verifiability for java-based systems. In Proceedings of the 44th International Conference on Software Engineering: Software Engineering in Practice. 297–306.
- Zetter (2023) Kim Zetter. 2023. The Untold Story of the Boldest Supply-Chain Hack Ever. Wired (2023).
## Appendix A Additional figures
<details>
<summary>extracted/6407037/figures/github-action-anon.png Details</summary>

### Visual Description
## Screenshot: GitHub Actions CI Build Log for Project TinyCC
### Overview
This image is a screenshot of a GitHub Actions workflow run page for a repository named "Project TinyCC". The specific run is identified as `#54`. The page displays the detailed log output for a job named "CI Build", which has succeeded. The interface is in dark mode.
### Components/Sections
The image is segmented into several key regions:
1. **Browser & Repository Header (Top):**
* Browser tab title: `Project TinyCC`
* URL: `https://github.com/[REDACTED]/actions/runs/1290257427/job/35976406616`
* GitHub repository navigation bar: Includes tabs for `Code`, `Pull requests`, `Actions` (selected), `Security`, `Insights`, `Settings`.
* Project Title: `Project TinyCC #54`
* Action Button: `Re-run all jobs` (top-right).
2. **Left Sidebar (Navigation):**
* `Summary`
* `Jobs` section with `CI Build` selected (highlighted with a blue bar and green checkmark).
* `Run details` subsection containing:
* `Usage`
* `Workflow file`
3. **Main Content Area - CI Build Job Log:**
* **Job Header:** `CI Build` with status `succeeded 18 hours ago in 34s`.
* **Log Search & Controls:** A `Search logs` bar and refresh/settings icons (top-right of log panel).
* **Expandable Log Sections:** Each section has a title, a status icon (green checkmark), and a duration.
* `Set up job` (0s)
* `Set up runner` (1s)
* `Configure` (0s)
* `Make` (11s) - *This section is expanded and contains the bulk of the visible text.*
* `Make check` (18s)
* `Run attestation` (0s) - *This section is also expanded.*
### Detailed Analysis / Content Details
**A. `Set up job` Section (Collapsed Summary):**
Lines 1-12 list environment setup details:
1. Current runner version: '2.321.0'
2. Runner name: 'NitroNorris'
3. Runner group name: 'Default'
4. Machine name: 'sandbox'
5. GITHUB_TOKEN Permissions
9. Secret source: Actions
10. Prepare workflow directory
11. Prepare all required actions
12. Complete job name: CI Build
**B. `Make` Section (Expanded - Compilation Log):**
This section details the compilation process using `gcc` and `make`. Key commands include:
* **Line 5:** `gcc -o tcc.o -c tcc.c -I. -DONE_SOURCE=0 -DTCC_GITHASH=\"2025-01-22 project_tinycc@d09be96\" -Wall -O2 -Wdeclaration-after-statement -Wno-unused-result`
* **Lines 6-16:** Similar `gcc` compilation commands for source files: `libtcc.c`, `tccpp.c`, `tccgen.c`, `tccdbg.c`, `tccelf.c`, `tccasm.c`, `tccrun.c`, `x86_64-gen.c`, `x86_64-link.c`, `i386-asm.c`.
* **Line 17:** `ar rcs libtcc.a libtcc.o tccpp.o tccgen.o tccdbg.o tccelf.o tccasm.o tccrun.o x86_64-gen.o x86_64-link.o i386-asm.o` (Creates static library `libtcc.a`).
* **Line 18:** `gcc -o tcc tcc.o libtcc.a -lm -ldl -lpthread` (Links the final `tcc` executable).
* **Lines 19-34:** Log from `make[1]` entering and leaving the directory `/app/github-runner/2.321.0/_work/stamp-demo-builds/stamp-demo-builds/project_tinycc/lib`. This sub-make compiles additional library components (`libtcc1.c`, `alloca.c`, `stdatomic.c`, etc.) using the just-built `tcc` compiler (`../tcc`).
* **Lines 35-36:** Post-compilation documentation generation:
* `perl /texi2pod.pl tcc-doc.texi tcc-doc.pod`
* `pod2man --section=1 --center="Tiny C Compiler" --release="0.9.28rc" tcc-doc.pod >tcc.1`
**C. `Run attestation` Section (Expanded - Security Attestation):**
This section runs an attestation hook and outputs a JSON structure.
* **Line 1:** `Run /bin/bash "$ATTESTATION_HOOK" "tcc"`
* **Line 4:** `Running ATTESTATION_HOOK (/app/github-runner/hooks/attestation.sh) with ARTIFACT_PATH=tcc`
* **Line 5:** `Waiting for attestation result...`
* **Line 6:** `Content of tcc.cert:`
* **Lines 7-14:** A JSON object containing:
* `"commit_hash": "d09be9662b313c5335ea3d8e0fdb7e6569dd80dc"`
* `"artifact_name": "tcc"`
* `"artifact_hash": "ba344a1b81e9a368c41b4465a3ae32bc7f7301b612b11cce9dd54bfd0b549406"`
* `"pcr0": "bXI6TGwHL1YXAlGqXPUwJal0Zx96/kjJ2t90gAnBelDj+BAGgC/fPpjL956GI00o"`
* `"pcr1": "S01bNmGz78Ep1JAMgOEm5M54PFIt5sAqKlv3zorkye4Z3bxi0S+HBxAShKdvaST"`
* `"pcr2": "zMUh6Xpqt1uHqewwXRCmF8Fwv0Z2vOSZrMAfEkpfzbN6WG4mkY9na/ADTxZG246"`
* `"attestation": "hEShATgi0FkRl6lpbW9KdWx1X2lkeCdpLTB1NzgwZDA4MzlhYWEwNjExLWVuYzAxOTQ4Y2I1MDI3NTk3MTdmZGlnZXN0ZlNlQTBMNG10aW1lc3RhbXABAAI1y2DQdkcGNyc7AAwDBtcjpMZycvVhcCUapc9TIAqXRnH0b+Smna33SAccF6U0P4EAaAL98+mMv3kbUjTSgwDBLTVs2YtPvv5kgkAyA4Sbkzng8Ui3mwCoqW/eVo1uTJ7hndvGl5L4cHEBEp29pJMCWDmQfrE+q3W4ep70BdEKYXwXC85na85JmswAV6Sn/MGfpYbiaRj2dr8NPPebbj0DWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
</details>
Figure 9. Screenshot of the GitHub Action CI running our prototype. The first section shows our runner configuration. The middle section the output from the main build step. The bottom section shows a report from the generated certification file including the PCR0–2 values, the source code commit hash, the artifact hash, and the signed attestation document.
## Appendix B GitHub Action integration
We show the required modification of an exemplary GitHub Action workflow file (Listing 1) into one that uses our A-B prototype (Listing 2). In addition, the repository owner needs to provide a Personal Access Token (PAT), so that we can register a new runner.
In the new version, the runs-on field now uses the name of the self-hosted A-B runner. Also, the repository no longer checkout its source manually, but this is done by the A-B runner before any other build code is being executed to avoid interference with the calculation of the repository commit hash. Next, we add a call to the attestation service by calling the provided ATTESTATION_HOOK environment variable which contains the path to the attestation executable provided by the runner. Optionally, we upload the attestation certificate together with the artifact.
⬇
name: CI for a Rust project
on:
push:
branches: [ " main " ]
pull_request:
branches: [ " main " ]
jobs:
lint:
runs - on: ubuntu -24.04
name: Lint (clippy & fmt)
steps:
- name: Check out code
uses: actions / checkout@v4.2.0
- name: Lint
run: cargo clippy -- verbose
- name: Format
run: cargo fmt -- -- check
build - and - test:
runs - on: ubuntu -24.04
name: Build and Test
steps:
- name: Check out code
uses: actions / checkout@v4.2.0
- name: Build
run: cargo build -- verbose
- name: Test
run: cargo test -- verbose
- name: Upload artifacts
uses: actions / upload - artifact@v4.6.0
with:
name: artifacts
path: |
target / debug / executable
_
Listing 1: A typical GitHub Action workflow file for a small Rust project.
⬇
name: CI for a Rust project
on:
push:
branches: [ " main " ]
pull_request:
branches: [ " main " ]
jobs:
lint:
runs - on: attested - build - runner
name: Lint (clippy & fmt)
steps:
- name: Lint
run: cargo clippy -- verbose
- name: Format
run: cargo fmt -- -- check
build - and - test:
runs - on: attested - build - runner
name: Build and Test
steps:
- name: Build
run: cargo build -- verbose
- name: Test
run: cargo test -- verbose
- name: Attestation
run: $ATTESTATION_HOOK target / debug / executable
- name: Upload artifacts
uses: actions / upload - artifact@v4.6.0
with:
name: artifacts and certificate
path: |
target / debug / executable
target / debug / executable. cert
Listing 2: The modified version of the GitHub Action workflow file using our prototype and providing attestation.
## Appendix C Security Properties
This section outlines the lemmas used for our formal verification. We use single letter variable names for better readability and to keep lemmas short. See Table 3 for the used notation.
Table 3. Notations used in Tamarin lemmas
| $c,ct,a,at,p,ip$ | c(code), ct(commit), a(artifact), at(attestation), p(pcr0), ip(incl. proof) |
| --- | --- |
| $Commit(c)$ | Artifact author commit code to RHP. |
| $Publish(c)$ | Publish code to adversary network. |
| $InitImage(c)$ | Initialize image with PCR and publish it via the adversary network. |
| $InitBuild(c)$ | Fetch Code from adversary network. |
| $Secure$ - $Commit(ct)$ | Store commit hash before entering untrusted execution state. |
| $Commit-$ $Verify(c,ct)$ | Verify the commit hash (h(c) = ct). |
| $Artifact(a)$ | Provide build artifact. |
| $Attestation(at)$ | Provide attestation document based on PCR from adversary network. |
| $LogEntry(ip)$ | Provide incl. proof of given log entry. |
| $LogVerify(f,ip)$ | Verify inclusion proof for given f where f = <ct,h(a),at> |
| $ATVerify(f,at)$ | Verify attestation for given f where f = <c,h(a),p>. |
Code manipulation
The following lemma proofs that the adversary is able to successfully compromise the code without detection when the verification controls are not used.
$$
\begin{split}\exists\,c,\,ct,\,\#i,\,\#j.\ \left(\left(\textrm{$Publish$}\left
(c\right)\ @\,\#i\right)\wedge\right.\\
\left.\left(\textrm{$SecureCommit$}\left(ct\right)\ @\,\#j\right)\right)\wedge
\left(\neg\left(\textrm{h}\left(c\right)=ct\right)\right)\end{split}
$$
This lemma proofs that the adversary is not able to compromise the code without detection when using the specific verification controls.
$$
\begin{split}\forall\,c,\,ct,\,\#i,\,\#j,\,\#k,\,\#l.\ \left(\left(\left(\left
(\textrm{$Commit$}\left(c\right)\ @\,\#i\right)\wedge\right.\right.\right.\\
\left.\left.\left.\left(\textrm{$Publish$}\left(c\right)\ @\,\#j\right)\right)
\wedge\left(\textrm{$SecureCommit$}\left(ct\right)\ @\,\#k\right)\right)\wedge
\right.\\
\left.\left(\textrm{$CommitVerify$}\left(c,\,ct\right)\ @\,\#l\right)
\Rightarrow\left(h\left(c\right)=ct\right)\right)\end{split}
$$
Build asset manipulation
$$
\begin{split}\exists\,c,\,ct,\,at,\,ip,\,\#i,\,\#j,\,\#k,\,\#l.\ \left(\left(
\left(\left(\left(\textrm{$Publish$}\left(c\right)\ @\,\#i\right)\wedge\right.
\right.\right.\right.\\
\left.\left.\left(\textrm{$SecureCommit$}\left(ct\right)\ @\,\#j\right)\right)
\wedge\left(\textrm{Attestation}\left(at\right)\ @\,\#k\right)\right)\wedge\\
\left.\left.\left(\textrm{$LogEntry$}\left(ip\right)\ @\,\#l\right)\right)
\wedge\left(\neg\left(h\left(c\right)=ct\right)\right)\right)\wedge\\
\left(\neg\left(h\left(<ct,h\left(c\right),h\left(c\right)>\right)=ip\right)
\right)\end{split}
$$
The lemma below verifies the inclusion proof using the action fact $LogVerify(<ct,h(a),at>,ip)$ , and Tamarin does not detect any trace, where such an attack is possible.
$$
\begin{split}\forall\,c,\,ct,\,a,\,at,\,ip,\,\#i,\,\#j,\,\#k.\ \\
\left(\left(\left(\textrm{$Publish$}\left(c\right)\ @\,\#i\right)\left(\textrm
{$CommitVerify$}\left(c,\,ct\right)\ @\,\#j\right)\right)\wedge\right.\\
\left.\left(\textrm{$LogVerify$}\left(<ct,\,h\left(a\right),at>,\,ip\right)\ @
\,\#k\right)\right)\\
\Rightarrow\left(\left(h\left(c\right)=ct\right)\wedge\left(h\left(<ct,\,h
\left(a\right),\,at>\right)=ip\right)\right)\end{split}
$$
Build infrastructure manipulation
$$
\begin{split}\exists\,c,\,ct,\,a,\,p,\,at,\,\#i,\,\#j,\,\#k,\,\#l,\,\#m.\ \\
\left(\left(\left(\left(\left(\textrm{$Publish$}\left(c\right)\ @\,\#i\right)
\left(\textrm{$SecureCommit$}\left(ct\right)\ @\,\#j\right)\right)\wedge\right
.\right.\right.\\
\left.\left.\left(\textrm{Artifact}\left(a\right)\ @\,\#k\right)\right)\wedge
\left(\textrm{InitImage}\left(p\right)\ @\,\#l\right)\right)\wedge\\
\left.\left(\textrm{Attestation}\left(at\right)\ @\,\#m\right)\right)\wedge
\left(\neg\left(<c,\,h\left(a\right),\,p>=at\right)\right)\end{split}
$$
The following lemma utilizes the verification control $ATVerify(..)$ provided by Attestable Builds. Tamarin cannot find any trace where an adversary is able to successfully compromise the build image without detection.
$$
\begin{split}\forall\,c,\,ct,\,a,\,p,\,at,\,\#i,\,\#j,\,\#k,\,\#l,\,\#m,\,\#n.
\ \\
\left(\left(\left(\left(\left(\left(\textrm{$Publish$}\left(c\right)\ @\,\#i
\right)\left(\textrm{$SecureCommit$}\left(ct\right)\ @\,\#j\right)\right)
\wedge\right.\right.\right.\right.\\
\left.\left.\left(\textrm{Artifact}\left(a\right)\ @\,\#k\right)\right)\wedge
\left(\textrm{InitImage}\left(p\right)\ @\,\#l\right)\right)\wedge\\
\left.\left(\textrm{Attestation}\left(at\right)\ @\,\#m\right)\right)\wedge\\
\left.\left(\textrm{$ATVerify$}\left(<c,\,h\left(a\right),p>,\,at\right)\ @\,
\#n\right)\right)\\
\Rightarrow\left(<c,\,h\left(a\right),\,p>=at\right)\end{split}
$$
Repository spoofing
The following lemma proofs that an adversary would be able to successfully spoof a repository when the corresponding verification control is not involved.
$$
\begin{split}\exists\,c,\,ct,\,a,\,at,\,ip,\,\#i,\,\#j,\,\#k,\,\#l,\,\#m,\,\#o
.\ \\
\left(\left(\left(\left(\left(\left(\left(\textrm{$Commit$}\left(c\right)\ @\,
\#i\right)\wedge\left(\textrm{$Publish$}\left(c\right)\ @\,\#j\right)\right)
\wedge\right.\right.\right.\right.\right.\\
\left.\left(\textrm{$SecureCommit$}\left(ct\right)\ @\,\#k\right)\right)\wedge
\\
\left.\left.\left(\textrm{$CommitVerify$}\left(c,\,ct\right)\ @\,\#l\right)
\right)\wedge\left(\textrm{$Artifact$}\left(a\right)\ @\,\#m\right)\right)
\wedge\\
\left.\left.\left(\textrm{$Attestation$}\left(at\right)\ @\,\#n\right)\right)
\wedge\left(\textrm{$LogEntry$}\left(ip\right)\ @\,\#o\right)\right)\\
\left(\neg\left(h\left(<h\left(c\right),\,h\left(a\right),\,at>\right)=ip
\right)\right)\end{split}
$$
Our model involves a verification step $RepositoryVerify(..)$ performed by the artifact author to mitigate repository spoofing. The following lemma proofs that an adversary cannot successfully spoof a repository when using Attestable Builds.
$$
\begin{split}\forall\,c,\,ct,\,a,\,at,\,ip,\,r,\,\#i,\,\#j,\,\#k,\,\#l,\,\#m,
\,\#o,\,\#p.\ \\
\left(\left(\left(\left(\left(\left(\left(\left(\textrm{$Commit$}\left(c\right
)\ @\,\#i\right)\wedge\left(\textrm{$Publish$}\left(c\right)\ @\,\#j\right)
\right)\wedge\right.\right.\right.\right.\right.\right.\\
\left.\left(\textrm{$SecureCommit$}\left(ct\right)\ @\,\#k\right)\right)\wedge
\\
\left.\left.\left(\textrm{$CommitVerify$}\left(c,\,ct\right)\ @\,\#l\right)
\right)\wedge\left(\textrm{$Artifact$}\left(a\right)\ @\,\#m\right)\right)
\wedge\\
\left.\left.\left(\textrm{$Attestation$}\left(at\right)\ @\,\#n\right)\right)
\wedge\left(\textrm{$LogEntry$}\left(ip\right)\ @\,\#o\right)\right)\\
\left.\left(\textrm{$RepositoryVerify$}\left(r,\,ip\right)\ @\,\#p\right)
\right)\Rightarrow\left(\left(h\left(c\right)=ct\right)\wedge\left(r=ip\right)
\right)\end{split}
$$
<details>
<summary>x9.png Details</summary>

### Visual Description
## Process Flow Diagram: Secure Build and Attestation Workflows
### Overview
The image displays a complex technical flowchart illustrating multiple parallel workflows for secure software build processes, infrastructure initialization, and attestation generation. The diagram is organized into several vertical lanes, each representing a distinct process flow initiated by a specific input. The primary language is English, with technical notation and identifiers.
### Components/Axes
The diagram is structured as a directed graph with the following key components:
1. **Starting Nodes (Ovals):** Located at the top of each vertical lane. Each is labeled with a pattern: `!KU( <identifier> ) @ #vk.<number>`. These represent the initiation points or inputs for each workflow.
2. **Intermediate Nodes (Ovals):** Labeled `#vf.<number> : isend`. These appear to be message or event forwarding steps.
3. **Process Steps (Green Rectangles):** The core of the diagram. Each box contains a step identifier (e.g., `#vr.1`), a descriptive function name, and parameters in parentheses. Steps are connected by arrows indicating sequence and data flow.
4. **Connectors:**
* **Solid Black Arrows:** Indicate the primary flow of control or data between process steps.
* **Red Dashed Arrows:** Connect the initial `!KU` nodes to the first `#vf` node in their respective lanes.
* **Grey Arrows:** Indicate secondary or data flow connections, often pointing to attestation or artifact provision steps.
### Detailed Analysis
The diagram details at least seven distinct, parallel workflows. Below is a transcription of the text and structure for each major lane, processed from left to right.
**Lane 1 (Far Left):**
* **Start:** `!KU( code.1 ) @ #vk.3`
* **Flow:** `#vf.2 : isend` → `In( <$A.1, code.1> )`
* **Process Steps:**
* `#vr.1 : init_build_infrastructure[InitBuild( code.1 )]`
* `CreateSecureCommit( $B, $E, code.1 )`
* `StartBuild( code.1 )`
* `#j : save_secure_commit[StoreSecureCommit( h(code.1) )]`
* `!ProvideSecureCommit( $B, $E, h(code.1) )`
**Lane 2:**
* **Start:** `!KU( artifact ) @ #vk.6`
* **Flow:** `#vf.3 : isend` → `In( <$A.2, artifact> )`
* **Process Steps:**
* `#vr.3 : init_build_infrastructure[InitBuild( artifact )]`
* `CreateSecureCommit( $B.3, $E.3, artifact )`
* `StartBuild( artifact )`
* `#vr.2 : start_build_process[Artifact( artifact )]`
* `!ProvideArtifact( artifact )`
**Lane 3:**
* **Start:** `!KU( code.2 ) @ #vk.9`
* **Flow:** `#vf.4 : isend` → `In( <$A.3, code.2> )`
* **Process Steps:**
* `#vr.5 : init_build_infrastructure[InitBuild( code.2 )]`
* `CreateSecureCommit( $B.1, $E.1, code.2 )`
* `StartBuild( code.2 )`
* `#vr.4 : save_secure_commit[StoreSecureCommit( h(code.2) )]`
* `!ProvideSecureCommit( $B.1, $E.1, h(code.2) )`
* `!ProvideAttestation( <h(code.2), h(artifact), pcr0> )`
* `#k : perform_attestation[Attestation( h(code.2), pcr0 )]`
* `!ProvideAttestation( <h(code.2), h(artifact), pcr0> )`
**Lane 4 (Center):**
* **Start:** `!KU( pcr0 ) @ #vk`
* **Flow:** `#vf.1 : isend` → `In( pcr0 )`
* **Process Step:**
* `!ProvideAttestation( <h(code.2), h(artifact), pcr0> )` (This step receives input from Lane 3).
**Lane 5:**
* **Start:** `!KU( code.3 ) @ #vk.16`
* **Flow:** `#vf.7 : isend` → `In( <$A.5, code.3> )`
* **Process Steps:**
* `#vr.10 : init_build_infrastructure[InitBuild( code.3 )]`
* `CreateSecureCommit( $B.4, $E.4, code.3 )`
* `StartBuild( code.3 )`
* `#vr.8 : save_secure_commit[StoreSecureCommit( h(code.3) )]`
* `!ProvideSecureCommit( $B.4, $E.4, h(code.3) )`
* `!ProvideAttestation( <h(code.3), h(AR1), pcr0.1> )`
* `#vr.9 : perform_attestation[Attestation( h(code.3), pcr0.1 )]`
* `!ProvideAttestation( <h(code.3), h(AR1), pcr0.1> )`
**Lane 6:**
* **Start:** `!KU( AR1 ) @ #vk.13`
* **Flow:** `#vf.6 : isend` → `In( <$A.4, AR1> )`
* **Process Steps:**
* `#vr.9 : init_build_infrastructure[InitBuild( AR1 )]`
* `CreateSecureCommit( $B.5, $E.5, AR1 )`
* `StartBuild( AR1 )`
* `#vr.7 : start_build_process[Artifact( AR1 )]`
* `!ProvideArtifact( AR1 )`
**Lane 7 (Right Side):**
* **Start:** `!KU( pcr0.1 ) @ #vk.10`
* **Flow:** `#vf.5 : isend` → `In( pcr0.1 )`
* **Process Step:**
* `#vr.11 : start_build_process[Artifact( AR2 )]`
* `!ProvideArtifact( AR2 )`
**Lane 8:**
* **Start:** `!KU( code.4 ) @ #vk.22`
* **Flow:** `#vf.9 : isend` → `In( <$A.7, code.4> )`
* **Process Steps:**
* `#vr.14 : init_build_infrastructure[InitBuild( code.4 )]`
* `CreateSecureCommit( $B.2, $E.2, code.4 )`
* `StartBuild( code.4 )`
* `#vr.13 : save_secure_commit[StoreSecureCommit( h(code.4) )]`
* `!ProvideSecureCommit( $B.2, $E.2, h(code.4) )`
**Lane 9 (Far Right):**
* **Start:** `!KU( AR2 ) @ #vk.19`
* **Flow:** `#vf.8 : isend` → `In( <$A.6, AR2> )`
* **Process Steps:**
* `#vr.12 : init_build_infrastructure[InitBuild( AR2 )]`
* `CreateSecureCommit( $B.6, $E.6, AR2 )`
* `StartBuild( AR2 )`
* **Additional Steps (connected via grey arrows):**
* `!ProvideSecureCommit( $B.2, $E.2, h(code.4) )` (from Lane 8)
* `#l : log_entry[LogEntry( H1 )]`
* `!ProvideLogEntry( $E.2, $C, H1 )`
### Key Observations
1. **Parallel Structure:** The diagram shows multiple independent but structurally similar workflows running in parallel, each handling different inputs (`code.1`, `artifact`, `code.2`, `pcr0`, `code.3`, `AR1`, `pcr0.1`, `code.4`, `AR2`).
2. **Common Pattern:** Most workflows follow a pattern: `Initiate` → `Forward Event` → `Initialize Build Infrastructure` → `Create Secure Commit` → `Start Build`. Some then proceed to `Save Commit` or `Start Build Process`.
3. **Attestation Generation:** Workflows for `code.2` and `code.3` include explicit steps for performing attestation (`#k`, `#vr.9`) and providing attestation data that references hashes (`h(...)`) of code and artifacts, as well as Platform Configuration Register values (`pcr0`, `pcr0.1`).
4. **Cross-Lane Dependencies:** There are clear dependencies between lanes. For example:
* The `pcr0` lane (Lane 4) receives attestation data generated in the `code.2` lane (Lane 3).
* The `pcr0.1` lane (Lane 7) triggers a build process for `AR2`.
* The `AR2` lane (Lane 9) receives a secure commit from the `code.4` lane (Lane 8) and generates a log entry.
5. **Notation:** The diagram uses a formal notation with symbols like `!` (likely indicating an output or message), `$` (variables or parameters), `h()` (hash function), and `#` (step or node identifier).
### Interpretation
This diagram models a sophisticated, secure software supply chain or trusted execution environment workflow. It demonstrates how different inputs (source code, artifacts, attestation measurements like PCRs) trigger parallel processes for building, committing, and attesting to the integrity of software components.
The key relationships are:
* **Build & Commit:** Source code or artifact inputs trigger infrastructure initialization and the creation of secure commits, which are then stored or provided as outputs.
* **Attestation:** The system generates cryptographic attestations linking the hashes of built code (`h(code)`) and artifacts (`h(artifact)`) with platform configuration state (`pcr0`). This creates verifiable proof of the build environment's integrity.
* **Chaining & Logging:** Later stages (like `AR2`) depend on outputs from earlier stages (secure commits from `code.4`), and actions are logged (`log_entry`), creating an auditable trail.
The overall purpose is to establish a verifiable chain of trust from initial inputs (code, artifacts) through the build process to final, attested outputs. The parallel lanes likely represent different components or stages of a larger system, with the attestation and logging steps serving as critical checkpoints for security and compliance. The complexity suggests this is a design for a high-assurance system where provenance and integrity are paramount.
</details>
Figure 10. This plot shows initial attack traces that Tamarin found. Traces like these show that our initial adversary assumptions would affect regular build systems. When enabling the A-B constraints, Tamarin fails to find any.
## Appendix D Additional evaluation material
This appendix includes additional data and plots from our evaluation (§ 4). Table 4 lists the dependencies and reverse dependencies for the unreproducible Debian packages that we have selected for our evaluation. Table 5 shows all individual durations from our main evaluation. Tables 6 – 7 show all individual durations from the job number experiments for XZ Utils and Verifier Client respectively. Figure 12 is a larger version of Figure 4. Figure 11 shows the stacked bar chart for the complex targets.
<details>
<summary>x10.png Details</summary>

### Visual Description
\n
## Stacked Bar Chart: Build Duration Comparison Across Compiler/Kernel Configurations
### Overview
The image displays a stacked bar chart comparing the overall duration (in seconds) of a build process across five different configurations (H, HS, E, ES, ES+) for three distinct compiler/kernel setups. The chart is divided into three vertical panels, each representing a different build environment. The primary finding is a dramatic difference in total build time between the first environment and the other two.
### Components/Axes
* **Chart Type:** Stacked Bar Chart (3 panels).
* **Y-Axis:** Labeled "Overall duration (s)". Scale ranges from 0 to over 5000 seconds, with major gridlines at 1000-second intervals.
* **X-Axis (per panel):** Five categorical configurations labeled: **H**, **HS**, **E**, **ES**, **ES+**.
* **Panel Titles (Top):**
1. **Clang (18.1.3)** - Left panel.
2. **Kernel (6.8.0, gcc)** - Center panel.
3. **Kernel (6.8.0, clang)** - Right panel.
* **Legend (Bottom Center):** Six color-coded components that make up the total build duration:
* **Start EIF** (Dark Blue)
* **Boot** (Light Blue)
* **Runner init** (Orange)
* **Checkout** (Light Orange/Peach)
* **Configure** (Light Green)
* **Build** (Dark Green)
### Detailed Analysis
**Panel 1: Clang (18.1.3)**
* **Trend:** Total duration increases steadily from configuration H to ES+.
* **Data Points (Approximate Total Duration):**
* H: ~3000 s
* HS: ~3400 s
* E: ~3600 s
* ES: ~4000 s
* ES+: ~5100 s
* **Component Breakdown:** The **Build** (dark green) phase overwhelmingly dominates each bar, accounting for the vast majority of the time. The other five components (Start EIF, Boot, Runner init, Checkout, Configure) are visible as thin bands at the base of each bar, collectively contributing a small fraction (estimated <200-300 s) to the total.
**Panel 2: Kernel (6.8.0, gcc)**
* **Trend:** Total duration increases from H to ES+, but the overall scale is an order of magnitude lower than Panel 1.
* **Data Points (Approximate Total Duration):**
* H: ~400 s
* HS: ~450 s
* E: ~500 s
* ES: ~550 s
* ES+: ~700 s
* **Component Breakdown:** The **Build** (dark green) phase is still the largest component. The **Checkout** (light orange) and **Configure** (light green) phases are more proportionally significant here than in Panel 1, though still minor compared to Build.
**Panel 3: Kernel (6.8.0, clang)**
* **Trend:** Similar increasing trend from H to ES+. Durations are slightly higher than the gcc kernel build but still far below the Clang-only build.
* **Data Points (Approximate Total Duration):**
* H: ~500 s
* HS: ~550 s
* E: ~600 s
* ES: ~650 s
* ES+: ~900 s
* **Component Breakdown:** Pattern is very similar to the gcc kernel build, with **Build** (dark green) as the dominant phase.
### Key Observations
1. **Massive Disparity in Scale:** The "Clang (18.1.3)" build process is dramatically slower (5-10x) than building the "Kernel (6.8.0)" with either gcc or clang.
2. **Consistent Configuration Impact:** Across all three panels, the **ES+** configuration results in the longest build time, followed by ES, E, HS, and H. This suggests ES+ is the most complex or feature-rich configuration.
3. **Dominant Phase:** The **Build** phase is the primary contributor to total duration in every single case.
4. **Compiler Comparison for Kernel:** Building the same kernel (6.8.0) with **clang** is consistently slower than with **gcc**, with the difference becoming more pronounced for the ES+ configuration (~900 s vs. ~700 s).
### Interpretation
This chart likely compares the performance of different build pipelines or toolchains for a large software project (possibly a Linux kernel or related components). The "Clang (18.1.3)" panel may represent building a large user-space component or the entire toolchain itself with Clang, which is a notoriously resource-intensive process. The other two panels show the time to compile the Linux kernel version 6.8.0 using two different compilers (gcc and clang).
The data demonstrates that the choice of compiler and build configuration has a profound impact on development cycle time. The **Build** phase's dominance indicates that compilation, not setup or checkout, is the critical bottleneck. The significant overhead of using Clang for the larger build (Panel 1) versus its more modest overhead when compiling the kernel (Panel 3 vs. Panel 2) suggests the performance characteristics are highly workload-dependent. For a development team, this data would argue for using gcc for kernel builds to save time, while highlighting that any process involving the standalone Clang 18.1.3 build is a major time investment. The consistent cost of the ES+ configuration implies it includes additional features or optimizations that substantially increase compilation complexity.
</details>
Figure 11. A variant of Figure 12. The complex targets clang and kernel are additionally built without sandboxes on the host H and enclave E.
<details>
<summary>x11.png Details</summary>

### Visual Description
\n
## Stacked Bar Chart: Build Duration Breakdown by Software Project and Configuration
### Overview
This image is a stacked bar chart comparing the overall build duration (in seconds) for nine different software projects. Each project is analyzed under three configurations: HS, ES, and ES+. The total duration for each configuration is broken down into six constituent phases, represented by different colors in the stacked bars.
### Components/Axes
* **Y-Axis:** Labeled "Overall duration (s)". The scale runs from 0 to 500 seconds, with major gridlines at 100-second intervals.
* **X-Axis (Panels):** The chart is divided into nine vertical panels, each dedicated to a specific software project. The project names and versions are listed at the top of each panel:
1. GProlog (1.6.0)
2. Hello (2.10)
3. IPXE (1.21.1)
4. Scheme48 (1.9.3)
5. NeoVIM (0.11.0)
6. LibSodium (1.0.20)
7. TinyCC (0.9.28)
8. Verifier Client
9. XZ Utils (5.6.3)
* **X-Axis (Categories):** Within each panel, three bars are plotted, labeled "HS", "ES", and "ES+" from left to right.
* **Legend:** Positioned at the bottom center of the chart. It defines the six phases that compose each stacked bar:
* **Start EIF** (Dark Blue)
* **Boot** (Light Blue)
* **Runner init** (Orange)
* **Checkout** (Light Orange/Peach)
* **Configure** (Light Green)
* **Build** (Dark Green)
### Detailed Analysis
The chart reveals significant variation in build times across projects and configurations. The **ES+** configuration consistently results in the longest build duration for every project. The **Build** phase (dark green) is the dominant contributor to total time in nearly all cases, especially for ES+. The **Configure** phase (light green) is the second most significant contributor in many ES+ bars.
**Project-Specific Data Points (Approximate Total Durations):**
* **GProlog (1.6.0):** HS ≈ 20s, ES ≈ 60s, ES+ ≈ 90s.
* **Hello (2.10):** HS ≈ 10s, ES ≈ 50s, ES+ ≈ 100s. The Configure segment is notably large in the ES+ bar.
* **IPXE (1.21.1):** HS ≈ 50s, ES ≈ 90s, ES+ ≈ 240s. The Build phase dominates the ES+ bar.
* **Scheme48 (1.9.3):** HS ≈ 20s, ES ≈ 60s, ES+ ≈ 80s.
* **NeoVIM (0.11.0):** This project has the longest build times. HS ≈ 270s, ES ≈ 280s, ES+ ≈ 490s. The ES+ bar is the tallest in the chart, with an enormous Build segment and a very large Configure segment.
* **LibSodium (1.0.20):** HS ≈ 40s, ES ≈ 80s, ES+ ≈ 190s.
* **TinyCC (0.9.28):** HS ≈ 10s, ES ≈ 40s, ES+ ≈ 50s. This project shows the smallest absolute increase from ES to ES+.
* **Verifier Client:** HS ≈ 80s, ES ≈ 110s, ES+ ≈ 160s.
* **XZ Utils (5.6.3):** HS ≈ 30s, ES ≈ 60s, ES+ ≈ 150s.
**Phase Contribution Trend:** For the ES+ configuration, the **Build** phase typically accounts for over 50% of the total duration. The **Start EIF**, **Boot**, **Runner init**, and **Checkout** phases combined generally constitute a smaller, more consistent portion of the time across all projects and configurations.
### Key Observations
1. **NeoVIM is an Outlier:** Its build times, particularly for ES+, are dramatically higher than all other projects, suggesting it is a much more complex or resource-intensive build.
2. **Configuration Impact:** Moving from HS to ES to ES+ almost universally increases build time. The jump from ES to ES+ is often the most significant.
3. **Phase Dominance:** The **Build** phase is the primary bottleneck. Optimizations targeting this phase would yield the greatest reduction in overall build time.
4. **Project Variability:** The absolute build times vary by an order of magnitude (e.g., TinyCC's ES+ at ~50s vs. NeoVIM's ES+ at ~490s), indicating vast differences in project scale or build process complexity.
### Interpretation
This chart is a performance analysis tool for a build system or continuous integration (CI) environment. The configurations (HS, ES, ES+) likely represent different levels of build isolation, resource allocation, or feature enablement (e.g., HS=Host System, ES=Emulated System, ES+=Emulated System with additional features).
The data demonstrates that **enabling more features or stricter isolation (moving to ES+) comes at a significant time cost**, primarily due to the **Build** phase expanding. This suggests the build process itself is sensitive to the underlying execution environment. The **Configure** phase also scales with configuration complexity for some projects.
The outlier status of **NeoVIM** implies its build process is either inherently more complex or is particularly poorly suited to the ES/ES+ environments. A systems engineer would use this data to:
* Identify which projects are most affected by configuration changes.
* Prioritize optimization efforts on the **Build** and **Configure** phases.
* Make informed decisions about the trade-off between build environment robustness (ES+) and developer/CI wait times.
* Investigate why NeoVIM's build scales so poorly compared to others.
</details>
Figure 12. A taller version of Figure 4. The duration of individual steps for the evaluated projects including the five unreproducible Debian packages and other artifacts. HS represents the baseline with a sandbox running directly on the host, ES (using containerd) and ES+ (using gVisor) are variants of our A-B prototype executing a sandboxed runner within an enclave.
Table 4. Selected unreproducible Debian packages based.
| Package | Number of Dependencies | Number of Reverse Dependencies |
| --- | --- | --- |
| ipxe | 3 | 2 |
| hello | 4 | 3 |
| gprolog | 4 | 2 |
| scheme48 | 4 | 2 |
| neovim | 16 | 39 |
Table 5. Build times for all targets and modes. Missing items indicate that they did not work out-of-the-box, e.g., because Amazon Linux 2023 is missing some dependencies in H mode. All values in seconds and averaged over three iterations.
| Clang (18.1.3) HS E | H $0.0$ $\mathrm{s}$ $71.0$ $\mathrm{s}$ | $0.0$ $\mathrm{s}$ $0.1$ $\mathrm{s}$ $3.1$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ $4.2$ $\mathrm{s}$ $4.1$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ $148.0$ $\mathrm{s}$ $137.2$ $\mathrm{s}$ | $145.0$ $\mathrm{s}$ $48.5$ $\mathrm{s}$ $36.7$ $\mathrm{s}$ | $48.4$ $\mathrm{s}$ $3211.3$ $\mathrm{s}$ $3270.9$ $\mathrm{s}$ | $2793.7$ $\mathrm{s}$ |
| --- | --- | --- | --- | --- | --- | --- | --- |
| ES | $46.4$ $\mathrm{s}$ | $9.1$ $\mathrm{s}$ | $4.1$ $\mathrm{s}$ | $117.2$ $\mathrm{s}$ | $35.6$ $\mathrm{s}$ | $3784.1$ $\mathrm{s}$ | |
| ES+ | $46.4$ $\mathrm{s}$ | $9.1$ $\mathrm{s}$ | $5.5$ $\mathrm{s}$ | $132.8$ $\mathrm{s}$ | $115.1$ $\mathrm{s}$ | $4748.5$ $\mathrm{s}$ | |
| Kernel (6.8.0, gcc) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.5$ $\mathrm{s}$ | $86.5$ $\mathrm{s}$ | $5.3$ $\mathrm{s}$ | $238.2$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $4.1$ $\mathrm{s}$ | $86.1$ $\mathrm{s}$ | $5.6$ $\mathrm{s}$ | $272.6$ $\mathrm{s}$ | |
| E | $70.8$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $69.5$ $\mathrm{s}$ | $4.8$ $\mathrm{s}$ | $246.5$ $\mathrm{s}$ | |
| ES | $46.4$ $\mathrm{s}$ | $9.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $68.9$ $\mathrm{s}$ | $5.0$ $\mathrm{s}$ | $279.4$ $\mathrm{s}$ | |
| ES+ | $46.4$ $\mathrm{s}$ | $9.1$ $\mathrm{s}$ | $5.7$ $\mathrm{s}$ | $91.0$ $\mathrm{s}$ | $9.6$ $\mathrm{s}$ | $533.8$ $\mathrm{s}$ | |
| Kernel (6.8.0, clang) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $80.1$ $\mathrm{s}$ | $7.5$ $\mathrm{s}$ | $410.2$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $4.1$ $\mathrm{s}$ | $81.3$ $\mathrm{s}$ | $7.4$ $\mathrm{s}$ | $423.0$ $\mathrm{s}$ | |
| E | $71.1$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $4.2$ $\mathrm{s}$ | $69.3$ $\mathrm{s}$ | $5.5$ $\mathrm{s}$ | $453.3$ $\mathrm{s}$ | |
| ES | $46.4$ $\mathrm{s}$ | $9.1$ $\mathrm{s}$ | $4.0$ $\mathrm{s}$ | $68.6$ $\mathrm{s}$ | $5.9$ $\mathrm{s}$ | $447.3$ $\mathrm{s}$ | |
| ES+ | $46.3$ $\mathrm{s}$ | $9.1$ $\mathrm{s}$ | $5.6$ $\mathrm{s}$ | $90.8$ $\mathrm{s}$ | $11.6$ $\mathrm{s}$ | $735.7$ $\mathrm{s}$ | |
| GProlog (1.6.0) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $1.3$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ | $12.8$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $4.2$ $\mathrm{s}$ | $1.3$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $14.9$ $\mathrm{s}$ | |
| E | $43.5$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $4.0$ $\mathrm{s}$ | $1.3$ $\mathrm{s}$ | $2.9$ $\mathrm{s}$ | $13.5$ $\mathrm{s}$ | |
| ES | $29.5$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ | $1.4$ $\mathrm{s}$ | $2.8$ $\mathrm{s}$ | $14.3$ $\mathrm{s}$ | |
| ES+ | $29.5$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.5$ $\mathrm{s}$ | $2.4$ $\mathrm{s}$ | $14.3$ $\mathrm{s}$ | $27.4$ $\mathrm{s}$ | |
| Hello (2.10) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.6$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $14.5$ $\mathrm{s}$ | $0.9$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $15.0$ $\mathrm{s}$ | $1.1$ $\mathrm{s}$ | |
| E | $43.7$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $11.5$ $\mathrm{s}$ | $0.9$ $\mathrm{s}$ | |
| ES | $29.7$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $4.3$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $11.0$ $\mathrm{s}$ | $1.0$ $\mathrm{s}$ | |
| ES+ | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.7$ $\mathrm{s}$ | $1.4$ $\mathrm{s}$ | $50.2$ $\mathrm{s}$ | $4.5$ $\mathrm{s}$ | |
| IPXE (1.21.1) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $0.0$ $\mathrm{s}$ | n/a |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $0.0$ $\mathrm{s}$ | $52.9$ $\mathrm{s}$ | |
| E | $43.5$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $4.0$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $0.0$ $\mathrm{s}$ | $45.8$ $\mathrm{s}$ | |
| ES | $29.6$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $0.0$ $\mathrm{s}$ | $48.6$ $\mathrm{s}$ | |
| ES+ | $29.5$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.5$ $\mathrm{s}$ | $1.6$ $\mathrm{s}$ | $0.0$ $\mathrm{s}$ | $196.4$ $\mathrm{s}$ | |
| Scheme48 (1.9.3) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $3.5$ $\mathrm{s}$ | $14.8$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $4.0$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ | $15.9$ $\mathrm{s}$ | |
| E | $43.4$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $2.8$ $\mathrm{s}$ | $15.2$ $\mathrm{s}$ | |
| ES | $29.5$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $2.7$ $\mathrm{s}$ | $16.0$ $\mathrm{s}$ | |
| ES+ | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.9$ $\mathrm{s}$ | $1.6$ $\mathrm{s}$ | $12.7$ $\mathrm{s}$ | $20.0$ $\mathrm{s}$ | |
| NeoVIM (0.11.0) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ | $0.9$ $\mathrm{s}$ | $66.1$ $\mathrm{s}$ | $255.9$ $\mathrm{s}$ |
| HS | $0.1$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ | $0.9$ $\mathrm{s}$ | $75.9$ $\mathrm{s}$ | $184.9$ $\mathrm{s}$ | |
| E | $43.5$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.9$ $\mathrm{s}$ | $65.3$ $\mathrm{s}$ | $158.9$ $\mathrm{s}$ | |
| ES | $29.8$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.9$ $\mathrm{s}$ | $70.0$ $\mathrm{s}$ | $167.3$ $\mathrm{s}$ | |
| ES+ | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.7$ $\mathrm{s}$ | $2.2$ $\mathrm{s}$ | $130.7$ $\mathrm{s}$ | $311.7$ $\mathrm{s}$ | |
| LibSodium (1.0.20) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $1.1$ $\mathrm{s}$ | $13.2$ $\mathrm{s}$ | $20.2$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $1.3$ $\mathrm{s}$ | $15.1$ $\mathrm{s}$ | $23.4$ $\mathrm{s}$ | |
| E | $43.8$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ | $0.8$ $\mathrm{s}$ | $10.6$ $\mathrm{s}$ | $19.9$ $\mathrm{s}$ | |
| ES | $29.5$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $4.0$ $\mathrm{s}$ | $0.8$ $\mathrm{s}$ | $11.5$ $\mathrm{s}$ | $22.1$ $\mathrm{s}$ | |
| ES+ | $29.6$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.9$ $\mathrm{s}$ | $1.7$ $\mathrm{s}$ | $46.1$ $\mathrm{s}$ | $94.9$ $\mathrm{s}$ | |
| TinyCC (0.9.28) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.6$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $4.5$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $4.5$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $5.7$ $\mathrm{s}$ | |
| E | $43.5$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $5.6$ $\mathrm{s}$ | |
| ES | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $4.2$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $5.8$ $\mathrm{s}$ | |
| ES+ | $29.5$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.6$ $\mathrm{s}$ | $1.6$ $\mathrm{s}$ | $0.4$ $\mathrm{s}$ | $8.5$ $\mathrm{s}$ | |
| Verifier Client | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ | $0.8$ $\mathrm{s}$ | $4.4$ $\mathrm{s}$ | $69.4$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $4.0$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $4.4$ $\mathrm{s}$ | $68.5$ $\mathrm{s}$ | |
| E | $43.4$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $3.2$ $\mathrm{s}$ | $70.5$ $\mathrm{s}$ | |
| ES | $29.5$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $4.1$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $2.7$ $\mathrm{s}$ | $70.4$ $\mathrm{s}$ | |
| ES+ | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.6$ $\mathrm{s}$ | $1.3$ $\mathrm{s}$ | $7.3$ $\mathrm{s}$ | $110.9$ $\mathrm{s}$ | |
| XZ Utils (5.6.3) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $9.7$ $\mathrm{s}$ | $13.6$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $11.1$ $\mathrm{s}$ | $16.1$ $\mathrm{s}$ | |
| E | $43.5$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $14.1$ $\mathrm{s}$ | |
| ES | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $8.2$ $\mathrm{s}$ | $14.8$ $\mathrm{s}$ | |
| ES+ | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.9$ $\mathrm{s}$ | $1.5$ $\mathrm{s}$ | $40.9$ $\mathrm{s}$ | $69.0$ $\mathrm{s}$ | |
Table 6. Build times for the C-based “XZ Utils across all modes and job number combinations. All values in seconds and averaged over three iterations.
| XZ Utils (5.6.3) (j1) | H | $0.1$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.6$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $9.7$ $\mathrm{s}$ | $36.1$ $\mathrm{s}$ |
| --- | --- | --- | --- | --- | --- | --- | --- |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $4.0$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $11.1$ $\mathrm{s}$ | $43.3$ $\mathrm{s}$ | |
| E | $43.4$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $36.3$ $\mathrm{s}$ | |
| ES | $29.5$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $4.1$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $8.2$ $\mathrm{s}$ | $38.7$ $\mathrm{s}$ | |
| ES+ | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $6.0$ $\mathrm{s}$ | $1.5$ $\mathrm{s}$ | $40.6$ $\mathrm{s}$ | $86.3$ $\mathrm{s}$ | |
| XZ Utils (5.6.3) (j2) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.6$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $9.7$ $\mathrm{s}$ | $19.4$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $4.0$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $11.2$ $\mathrm{s}$ | $23.1$ $\mathrm{s}$ | |
| E | $43.5$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.6$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $20.4$ $\mathrm{s}$ | |
| ES | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $8.3$ $\mathrm{s}$ | $21.5$ $\mathrm{s}$ | |
| ES+ | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $6.0$ $\mathrm{s}$ | $1.6$ $\mathrm{s}$ | $41.1$ $\mathrm{s}$ | $69.2$ $\mathrm{s}$ | |
| XZ Utils (5.6.3) (j3) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $9.7$ $\mathrm{s}$ | $15.7$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $11.1$ $\mathrm{s}$ | $18.6$ $\mathrm{s}$ | |
| E | $43.5$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $4.0$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $16.3$ $\mathrm{s}$ | |
| ES | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $8.3$ $\mathrm{s}$ | $17.3$ $\mathrm{s}$ | |
| ES+ | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.5$ $\mathrm{s}$ | $1.5$ $\mathrm{s}$ | $40.7$ $\mathrm{s}$ | $66.9$ $\mathrm{s}$ | |
| XZ Utils (5.6.3) (j4) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.6$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $9.7$ $\mathrm{s}$ | $13.6$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $4.1$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $11.2$ $\mathrm{s}$ | $16.1$ $\mathrm{s}$ | |
| E | $43.5$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $4.2$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $8.2$ $\mathrm{s}$ | $14.2$ $\mathrm{s}$ | |
| ES | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $8.3$ $\mathrm{s}$ | $14.9$ $\mathrm{s}$ | |
| ES+ | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.5$ $\mathrm{s}$ | $1.5$ $\mathrm{s}$ | $40.7$ $\mathrm{s}$ | $69.0$ $\mathrm{s}$ | |
| XZ Utils (5.6.3) (j5) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.5$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $9.7$ $\mathrm{s}$ | $13.7$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $11.2$ $\mathrm{s}$ | $16.2$ $\mathrm{s}$ | |
| E | $43.4$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $14.3$ $\mathrm{s}$ | |
| ES | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $8.2$ $\mathrm{s}$ | $14.8$ $\mathrm{s}$ | |
| ES+ | $29.5$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.7$ $\mathrm{s}$ | $1.6$ $\mathrm{s}$ | $41.0$ $\mathrm{s}$ | $70.5$ $\mathrm{s}$ | |
| XZ Utils (5.6.3) (j6) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.4$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $9.8$ $\mathrm{s}$ | $13.8$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $11.2$ $\mathrm{s}$ | $16.3$ $\mathrm{s}$ | |
| E | $43.8$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $8.2$ $\mathrm{s}$ | $14.4$ $\mathrm{s}$ | |
| ES | $29.5$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $4.0$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $8.3$ $\mathrm{s}$ | $15.2$ $\mathrm{s}$ | |
| ES+ | $29.8$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.9$ $\mathrm{s}$ | $1.6$ $\mathrm{s}$ | $41.3$ $\mathrm{s}$ | $71.2$ $\mathrm{s}$ | |
| XZ Utils (5.6.3) (j7) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.4$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $9.7$ $\mathrm{s}$ | $13.8$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $4.1$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $11.1$ $\mathrm{s}$ | $16.4$ $\mathrm{s}$ | |
| E | $43.6$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $14.5$ $\mathrm{s}$ | |
| ES | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $8.3$ $\mathrm{s}$ | $15.2$ $\mathrm{s}$ | |
| ES+ | $29.5$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.6$ $\mathrm{s}$ | $1.5$ $\mathrm{s}$ | $40.4$ $\mathrm{s}$ | $71.2$ $\mathrm{s}$ | |
| XZ Utils (5.6.3) (j8) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.5$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $9.7$ $\mathrm{s}$ | $13.7$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $11.2$ $\mathrm{s}$ | $16.4$ $\mathrm{s}$ | |
| E | $43.5$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $14.5$ $\mathrm{s}$ | |
| ES | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $4.1$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $8.3$ $\mathrm{s}$ | $15.2$ $\mathrm{s}$ | |
| ES+ | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.6$ $\mathrm{s}$ | $1.5$ $\mathrm{s}$ | $41.1$ $\mathrm{s}$ | $72.2$ $\mathrm{s}$ | |
Table 7. Build times for the Rust-based “Verifier Client” across all modes and job number combinations. All values in seconds and averaged over three iterations.
| Verifier Client (j1) HS E | H $0.0$ $\mathrm{s}$ $43.4$ $\mathrm{s}$ | $0.0$ $\mathrm{s}$ $0.1$ $\mathrm{s}$ $3.1$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ $3.9$ $\mathrm{s}$ $3.9$ $\mathrm{s}$ | $3.6$ $\mathrm{s}$ $0.6$ $\mathrm{s}$ $0.6$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ $4.6$ $\mathrm{s}$ $3.5$ $\mathrm{s}$ | $4.3$ $\mathrm{s}$ $185.1$ $\mathrm{s}$ $181.2$ $\mathrm{s}$ | $186.5$ $\mathrm{s}$ |
| --- | --- | --- | --- | --- | --- | --- | --- |
| ES | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $2.7$ $\mathrm{s}$ | $181.2$ $\mathrm{s}$ | |
| ES+ | $29.5$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.8$ $\mathrm{s}$ | $1.4$ $\mathrm{s}$ | $7.3$ $\mathrm{s}$ | $230.4$ $\mathrm{s}$ | |
| Verifier Client (j2) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.6$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $4.4$ $\mathrm{s}$ | $100.0$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $4.1$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $4.2$ $\mathrm{s}$ | $99.1$ $\mathrm{s}$ | |
| E | $43.4$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $97.8$ $\mathrm{s}$ | |
| ES | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $2.8$ $\mathrm{s}$ | $98.3$ $\mathrm{s}$ | |
| ES+ | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.9$ $\mathrm{s}$ | $1.4$ $\mathrm{s}$ | $7.3$ $\mathrm{s}$ | $138.8$ $\mathrm{s}$ | |
| Verifier Client (j3) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.4$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $4.3$ $\mathrm{s}$ | $80.2$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $4.2$ $\mathrm{s}$ | $79.4$ $\mathrm{s}$ | |
| E | $43.4$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $7.1$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $3.2$ $\mathrm{s}$ | $80.1$ $\mathrm{s}$ | |
| ES | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $4.0$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $2.7$ $\mathrm{s}$ | $80.6$ $\mathrm{s}$ | |
| ES+ | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.9$ $\mathrm{s}$ | $1.3$ $\mathrm{s}$ | $7.3$ $\mathrm{s}$ | $114.0$ $\mathrm{s}$ | |
| Verifier Client (j4) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $4.3$ $\mathrm{s}$ | $69.2$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $4.1$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $4.7$ $\mathrm{s}$ | $68.3$ $\mathrm{s}$ | |
| E | $43.4$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.6$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $3.2$ $\mathrm{s}$ | $70.2$ $\mathrm{s}$ | |
| ES | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $2.7$ $\mathrm{s}$ | $70.4$ $\mathrm{s}$ | |
| ES+ | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.6$ $\mathrm{s}$ | $1.4$ $\mathrm{s}$ | $7.5$ $\mathrm{s}$ | $110.6$ $\mathrm{s}$ | |
| Verifier Client (j5) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.6$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $4.2$ $\mathrm{s}$ | $69.5$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $4.4$ $\mathrm{s}$ | $68.7$ $\mathrm{s}$ | |
| E | $43.5$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $3.4$ $\mathrm{s}$ | $70.7$ $\mathrm{s}$ | |
| ES | $29.5$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $4.1$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $2.9$ $\mathrm{s}$ | $71.7$ $\mathrm{s}$ | |
| ES+ | $29.7$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.6$ $\mathrm{s}$ | $1.3$ $\mathrm{s}$ | $7.5$ $\mathrm{s}$ | $112.8$ $\mathrm{s}$ | |
| Verifier Client (j6) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.6$ $\mathrm{s}$ | $1.0$ $\mathrm{s}$ | $4.3$ $\mathrm{s}$ | $70.8$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $4.4$ $\mathrm{s}$ | $69.7$ $\mathrm{s}$ | |
| E | $43.8$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $4.2$ $\mathrm{s}$ | $72.2$ $\mathrm{s}$ | |
| ES | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $2.7$ $\mathrm{s}$ | $72.1$ $\mathrm{s}$ | |
| ES+ | $29.7$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.8$ $\mathrm{s}$ | $1.3$ $\mathrm{s}$ | $7.3$ $\mathrm{s}$ | $115.3$ $\mathrm{s}$ | |
| Verifier Client (j7) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.7$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $4.2$ $\mathrm{s}$ | $70.4$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $4.2$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $4.6$ $\mathrm{s}$ | $69.3$ $\mathrm{s}$ | |
| E | $43.4$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.7$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $72.3$ $\mathrm{s}$ | |
| ES | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $3.6$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $3.2$ $\mathrm{s}$ | $72.1$ $\mathrm{s}$ | |
| ES+ | $29.5$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.7$ $\mathrm{s}$ | $1.3$ $\mathrm{s}$ | $7.5$ $\mathrm{s}$ | $117.0$ $\mathrm{s}$ | |
| Verifier Client (j8) | H | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.5$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $4.2$ $\mathrm{s}$ | $71.3$ $\mathrm{s}$ |
| HS | $0.0$ $\mathrm{s}$ | $0.1$ $\mathrm{s}$ | $3.9$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $4.2$ $\mathrm{s}$ | $70.3$ $\mathrm{s}$ | |
| E | $43.4$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $3.8$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $3.1$ $\mathrm{s}$ | $73.1$ $\mathrm{s}$ | |
| ES | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $4.0$ $\mathrm{s}$ | $0.6$ $\mathrm{s}$ | $3.2$ $\mathrm{s}$ | $73.3$ $\mathrm{s}$ | |
| ES+ | $29.4$ $\mathrm{s}$ | $8.1$ $\mathrm{s}$ | $5.9$ $\mathrm{s}$ | $1.4$ $\mathrm{s}$ | $7.4$ $\mathrm{s}$ | $120.0$ $\mathrm{s}$ | |