# Attestable builds: compiling verifiable binaries on untrusted systems using trusted execution environments
**Authors**: Daniel Hugenroth, Mario Lins, René Mayrhofer, Alastair R. Beresford
> dh623@cam.ac.uk0000-0003-3413-1722University of CambridgeCambridgeUnited Kingdom
> mario.lins@ins.jku.at0000-0003-1713-3347Johannes Kepler UniversityLinzAustria
> rm@ins.jku.at0000-0003-1566-4646Johannes Kepler UniversityLinzAustria
> arb33@cam.ac.uk0000-0003-0818-6535University of CambridgeCambridgeUnited 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: DevOps Pipeline Architecture
### Overview
The diagram illustrates a DevOps pipeline workflow, depicting the flow of code artifacts from development to deployment. It uses standardized DevOps icons and directional arrows to represent the progression of software artifacts through various stages.
### Components/Axes
1. **DEVs** (Top-left)
- Represented by three human silhouettes with laptops
- Position: Leftmost section of the diagram
- Function: Code contributors/developers
2. **RHP** (Repository Hosting Platform)
- Icon: Cylinder with cloud base
- Position: Center-left
- Function: Version control repository
3. **CI/CD** (Continuous Integration/Continuous Deployment)
- Icon: Gear mechanism
- Position: Center-right
- Function: Automated build/test/deployment pipeline
4. **BSP** (Build System Platform)
- Position: Between RHP and Artifact
- Function: Artifact generation system
5. **Artifact** (Final Output)
- Icon: Cube with three visible faces
- Position: Far right
- Function: Deployable software package
6. **CSP** (Cloud Service Provider)
- Icon: Cloud with "CSP" label
- Position: Bottom center
- Function: Infrastructure provider
### Flow Direction
- Left-to-right progression: DEVs → RHP → BSP → Artifact
- Vertical connection: RHP ↔ CSP (dashed line)
- All components connected by solid arrows except CSP connection
### Key Observations
1. **Linear Workflow**: Clear sequential progression from code development to deployment
2. **Automation Emphasis**: Gear icon highlights CI/CD automation
3. **Cloud Integration**: CSP positioned as foundational infrastructure
4. **Artifact Standardization**: Cube icon suggests standardized packaging format
### Interpretation
This diagram represents a typical DevOps pipeline architecture where:
- Developers (DEVs) commit code to a version-controlled repository (RHP)
- The repository triggers automated CI/CD processes (gear icon)
- These processes generate deployable artifacts (cube icon)
- The entire pipeline operates on cloud infrastructure (CSP)
- The dashed line between RHP and CSP indicates optional cloud dependency
The architecture emphasizes automation (CI/CD), standardization (artifact cube), and cloud-native deployment. The absence of feedback loops suggests a linear deployment model rather than continuous delivery with rollback capabilities. The cloud provider's central position underscores modern infrastructure-as-code practices.
</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
## Flowchart: Secure Build Process with Attestation
### Overview
This flowchart illustrates a secure build process involving hardware-based attestation, enclave computing, and artifact verification. It outlines steps from code commit to final artifact validation, emphasizing trust anchors, secure execution environments, and cryptographic verification.
### Components/Axes
1. **Key Components**:
- **Build Trigger**: Initiates the process (Step 1)
- **Hypervisor**: Manages virtualization (Step 2)
- **Hardware Trust Anchor**: Includes PCR0-2, CT, A (Step 7)
- **Instance Manager**: Coordinates build instances (Step 2)
- **Enclave Client**: Manages secure enclave operations (Step 3)
- **Build Runner**: Executes build process (Step 4)
- **Untrusted Build Process**: Non-secure build components (Step 6)
- **Sandbox**: Isolated execution environment (Step 8)
- **TEE (Trusted Execution Environment)**: e.g., Nitro Enclave (Step 8)
- **Host Instance**: Physical/cloud infrastructure (Step 8)
- **Log**: Central repository for attestation documents (Step 9)
- **RHP (Repository Hosting Platform)**: e.g., GitHub (Step 4)
- **User Interaction**: Final verification step (Step 11)
2. **Flow Direction**:
- Left-to-right progression from code commit to artifact validation
- Vertical connections between components (e.g., build runner → sandbox)
- Feedback loops for attestation and verification
### Detailed Analysis
1. **Build Process Flow**:
- **Step 1-3**: Code commit (CT) triggers build instance creation
- **Step 4-5**: Build runner executes in sandbox, reporting commit hash
- **Step 6-7**: Untrusted build process generates artifact hash (A)
- **Step 8**: TEE sandbox executes in host instance (AWS EC2)
- **Step 9**: Attestation document (AT) published to log
- **Step 10-11**: Artifact and AT published to RHP
- **Step 12**: User verifies claim: "A was built using PCR0-2 from CT"
2. **Security Mechanisms**:
- Hardware Trust Anchor (green box) anchors PCR measurements
- Enclave client (Step 3) manages secure enclave operations
- Sandbox (Step 8) isolates untrusted build process
- TEE (Step 8) provides memory encryption and integrity
3. **Artifact Verification**:
- Commit hash (CT) and artifact hash (A) cryptographically linked
- Attestation document (AT) combines PCR0-2, CT, and A
- Final verification checks PCR0-2 against CT
### Key Observations
1. **Trust Chain**:
- Hardware Trust Anchor (Step 7) provides root of trust
- PCR0-2 measurements anchor build environment state
- CT (commit hash) anchors source code integrity
2. **Isolation Layers**:
- Sandbox (Step 8) isolates untrusted build process
- TEE (Step 8) provides additional memory protection
- Enclave client (Step 3) manages secure communication
3. **Verification Flow**:
- Attestation document (Step 9) combines multiple trust elements
- Final verification (Step 12) checks cryptographic proof
- Optional endorsement/revocation checks (Step 11)
### Interpretation
This diagram demonstrates a multi-layered security approach for build artifact verification:
1. **Hardware Root of Trust**: PCR0-2 measurements from the Hardware Trust Anchor (e.g., AWS Nitro Card) provide foundational trust.
2. **Secure Execution**: The build process occurs in isolated environments (sandbox/TEE) to prevent tampering.
3. **Cryptographic Verification**: The attestation document (AT) combines hardware measurements, commit hashes, and artifact hashes for end-to-end verification.
4. **User Validation**: Final step allows users to verify claims about build provenance, ensuring artifacts were built using specific hardware configurations.
The process emphasizes defense-in-depth security, combining hardware isolation, cryptographic attestation, and secure execution environments to prevent supply chain attacks and ensure build integrity.
</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
## Diagram: Data Processing Pipeline with Cloud Servers and Database
### Overview
The diagram illustrates a multi-stage data processing workflow originating from a source document (`</>`), passing through three cloud servers (B1, B2, B3), generating identical hexadecimal outputs (`0xfe1423cd...`), and concluding with a database (`L`) and user interaction. Dotted lines connect three document-like elements (C1, C2, C3) to the hexadecimal outputs, suggesting auxiliary relationships.
### Components/Axes
- **Source Document**: Labeled `</>`, initiating the workflow.
- **Cloud Servers**:
- B1 (blue gear), B2 (green gear), B3 (yellow gear).
- **Hexadecimal Outputs**: Three identical strings (`0xfe1423cd...`) generated by each server.
- **Database**: Labeled `L`, receiving input from the hexadecimal outputs.
- **User**: Represented by a silhouette icon, connected bidirectionally to the database.
- **Auxiliary Documents**: C1 (blue), C2 (green), C3 (yellow), linked via dotted lines to the hexadecimal outputs.
### Detailed Analysis
- **Flow Direction**:
- The source document (`</>`) feeds into all three cloud servers (B1, B2, B3) via solid arrows.
- Each server produces the same hexadecimal output (`0xfe1423cd...`), which is then routed to the database (`L`).
- The database (`L`) has a bidirectional arrow to the user icon, implying data retrieval or user interaction.
- Dotted lines from C1, C2, C3 to the hexadecimal outputs suggest non-primary dependencies or secondary data paths.
- **Hexadecimal Output Consistency**:
- All three cloud servers generate identical outputs (`0xfe1423cd...`), which may indicate:
- A placeholder value for demonstration.
- A standardized output across servers (e.g., checksum, token, or identifier).
- A potential error or oversight in the diagram (if uniqueness was intended).
- **Color Coding**:
- Cloud servers use distinct gear colors (blue, green, yellow), possibly denoting:
- Different environments (e.g., development, testing, production).
- Resource allocation or priority levels.
- Functional roles (e.g., B1 for encryption, B2 for validation).
### Key Observations
1. **Repetitive Outputs**: The identical hexadecimal values across servers raise questions about the purpose of multiple servers if outputs are uniform.
2. **Dotted Line Relationships**: C1, C2, C3 are visually disconnected from the main workflow, suggesting auxiliary or optional data paths.
3. **User-Database Interaction**: The bidirectional arrow between `L` and the user implies real-time data access or feedback loops.
### Interpretation
This diagram likely represents a **distributed data processing system** where:
- The source document is processed in parallel by three cloud servers (B1–B3), possibly for redundancy, load balancing, or parallel computation.
- The consistent hexadecimal output (`0xfe1423cd...`) could represent a shared identifier, token, or checksum critical to the workflow.
- The database (`L`) acts as a central repository, while the user interacts with it, suggesting a client-server architecture.
- The dotted lines from C1–C3 to the hexadecimal outputs may indicate metadata, logging, or secondary data streams not central to the primary workflow.
**Uncertainties**:
- The purpose of C1–C3 remains unclear without additional context.
- The identical hexadecimal outputs may be intentional (e.g., a shared key) or an oversight.
- The color-coded gears lack explicit legends, leaving their significance open to interpretation.
</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
## Bar Chart: Overall Duration Comparison Across Software Tools and Environments
### Overview
The chart compares the overall duration (in seconds) of software tools across three environments (HS, ES, ES+) segmented by six process components: Start EIF, Boot, Runner init, Checkout, Configure, and Build. Each tool's duration is represented as a stacked bar, with colors corresponding to the legend.
### Components/Axes
- **X-axis**: Software tools (GProlog, Hello, IPXE, Scheme48, NeoVIM, LibSodium, TinyCC, Verifier Client, XZ Utils) with subcategories HS, ES, ES+.
- **Y-axis**: Overall duration (s), scaled from 0 to 500.
- **Legend**:
- Blue: Start EIF
- Light blue: Boot
- Orange: Runner init
- Light orange: Checkout
- Light green: Configure
- Green: Build
### Detailed Analysis
1. **GProlog (1.6.0)**:
- HS: Small green (Build), tiny blue (Start EIF), small orange (Runner init).
- ES: Slightly larger green, blue, and orange segments.
- ES+: Green dominates, with minimal contributions from other components.
2. **Hello (2.1.0)**:
- HS: Light green (Configure) and green (Build) segments.
- ES: Light green and green segments larger than HS.
- ES+: Light green and green segments dominate, with a small blue (Start EIF).
3. **IPXE (1.21.1)**:
- HS: Green (Build) and light green (Configure) segments.
- ES: Green and light green segments larger than HS.
- ES+: Green dominates, with a small blue (Start EIF).
4. **Scheme48 (1.9.3)**:
- HS: Small green (Build), blue (Start EIF), and orange (Runner init).
- ES: Green and blue segments larger than HS.
- ES+: Green dominates, with minimal other components.
5. **NeoVIM (0.11.0)**:
- HS: Tall green (Build) and light green (Configure) segments.
- ES: Green and light green segments larger than HS.
- ES+: Green dominates, with a small blue (Start EIF).
6. **LibSodium (1.0.20)**:
- HS: Small green (Build), blue (Start EIF), and orange (Runner init).
- ES: Green and blue segments larger than HS.
- ES+: Green dominates, with minimal other components.
7. **TinyCC (0.9.28)**:
- HS: Tiny green (Build), blue (Start EIF), and orange (Runner init).
- ES: Green and blue segments larger than HS.
- ES+: Green dominates, with minimal other components.
8. **Verifier Client**:
- HS: Green (Build) and light green (Configure) segments.
- ES: Green and light green segments larger than HS.
- ES+: Green dominates, with a small blue (Start EIF).
9. **XZ Utils (5.6.3)**:
- HS: Small green (Build), blue (Start EIF), and orange (Runner init).
- ES: Green and blue segments larger than HS.
- ES+: Green dominates, with minimal other components.
### Key Observations
- **Build Phase Dominance**: The green (Build) segment is consistently the largest contributor to overall duration across all tools and environments.
- **Environmental Impact**: ES+ often shows longer durations than ES, but this varies (e.g., Hello and XZ Utils show smaller differences).
- **Outliers**: NeoVIM (0.11.0) and Verifier Client have the highest overall durations, driven by prolonged Build and Configure phases.
- **Minor Components**: Start EIF (blue) and Runner init (orange) are consistently the smallest segments.
### Interpretation
The data highlights that the **Build phase** is the most time-intensive process across all tools, suggesting optimization opportunities in build systems. Environmental differences (HS, ES, ES+) have variable impacts, with ES+ occasionally increasing duration but not universally. Tools like NeoVIM and Verifier Client exhibit higher complexity or resource demands, as reflected in their prolonged durations. The minimal contribution of Start EIF and Runner init indicates these phases are relatively efficient or standardized. This analysis underscores the importance of targeting Build and Configure phases for performance improvements.
</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 Graphs: Build Duration vs. Number of Jobs (make -j)
### Overview
The image contains two line graphs comparing build durations for two software components ("XZ Utils" and "Verifier Client") across varying numbers of parallel jobs (1–8). Each graph includes two data series: "HS" (solid green line) and "ES+" (dashed green line). The y-axis represents build duration in seconds, while the x-axis represents the number of jobs.
---
### Components/Axes
1. **XZ Utils Graph**:
- **X-axis**: "Num jobs (make -j)" (1–8).
- **Y-axis**: "Build duration (s)" (0–75s, linear scale).
- **Legend**:
- Solid green: "HS"
- Dashed green: "ES+"
- **Legend Position**: Top-right corner.
2. **Verifier Client Graph**:
- **X-axis**: "Num jobs (make -j)" (1–8).
- **Y-axis**: "Build duration (s)" (0–200s, linear scale).
- **Legend**:
- Solid green: "HS"
- Dashed green: "ES+"
- **Legend Position**: Top-right corner.
---
### Detailed Analysis
#### XZ Utils Graph
- **HS (Solid Green)**:
- Starts at ~75s for 1 job.
- Drops sharply to ~25s at 2 jobs.
- Plateaus at ~25s for jobs 3–8.
- **ES+ (Dashed Green)**:
- Starts at ~150s for 1 job.
- Decreases to ~75s at 2 jobs.
- Stabilizes at ~75s for jobs 3–8.
#### Verifier Client Graph
- **HS (Solid Green)**:
- Starts at ~200s for 1 job.
- Drops to ~100s at 2 jobs.
- Remains flat at ~100s for jobs 3–8.
- **ES+ (Dashed Green)**:
- Starts at ~250s for 1 job.
- Decreases to ~125s at 2 jobs.
- Stabilizes at ~125s for jobs 3–8.
---
### Key Observations
1. **Initial Job Impact**: Both data series show a steep decline in build duration when increasing jobs from 1 to 2.
2. **Diminishing Returns**: After 2 jobs, build durations stabilize, indicating minimal improvement with additional jobs.
3. **Performance Gap**: "ES+" consistently has longer build durations than "HS" in both graphs.
4. **Scale Differences**: The Verifier Client graph uses a larger y-axis scale (0–200s) compared to XZ Utils (0–75s), reflecting inherently longer build times.
---
### Interpretation
- **Parallel Job Efficiency**: The sharp decline in build duration for the first two jobs suggests that parallelism significantly reduces build times, but adding more jobs yields diminishing returns.
- **Component Complexity**: The Verifier Client’s longer build times (e.g., ~200s vs. ~75s for XZ Utils) imply it is computationally more intensive.
- **Algorithm/Implementation Differences**: The persistent gap between "HS" and "ES+" may reflect differences in code optimization, dependencies, or resource utilization between the two components.
- **Practical Implication**: For both components, using 2 jobs is likely optimal, as further parallelization does not meaningfully reduce build duration.
---
### Spatial Grounding & Trend Verification
- **Legend Alignment**: Both legends are positioned in the top-right corner, matching the color coding (solid green = HS, dashed green = ES+).
- **Trend Consistency**: The observed trends (sharp decline followed by plateau) align with the visual slopes of the lines in both graphs.
</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
## Bar Charts: Build Duration Comparison Across Configurations
### Overview
The image contains three side-by-side bar charts comparing build durations (in seconds) for different software configurations. Each chart represents a distinct toolchain or compiler version, with consistent x-axis categories (H, HS, E, ES, ES+) and y-axis scales tailored to the data range.
---
### Components/Axes
1. **X-Axes (Categories)**:
- All charts share identical x-axis labels: `H`, `HS`, `E`, `ES`, `ES+`.
- Positioned at the bottom of each chart, evenly spaced.
2. **Y-Axes (Build Duration)**:
- **Left Chart (Clang)**: Labeled "Build duration (s)", scaled from 0 to 4000 in increments of 2000.
- **Middle Chart (Kernel GCC)**: Scaled from 0 to 600 in increments of 200.
- **Right Chart (Kernel Clang)**: Scaled from 0 to 800 in increments of 200.
3. **Bars**:
- Black bars represent build durations for each configuration.
- Error bars (small horizontal lines atop bars) indicate variability, though values are not explicitly labeled.
4. **Titles**:
- **Left**: "Clang (18.1.3)" (top-center).
- **Middle**: "Kernel (6.8.0, gcc)" (top-center).
- **Right**: "Kernel (6.8.0, clang)" (top-center).
---
### Detailed Analysis
#### Left Chart (Clang 18.1.3)
- **Trend**: Build duration increases monotonically from `H` to `ES+`.
- **Values**:
- `H`: ~2500s
- `HS`: ~3000s
- `E`: ~3200s
- `ES`: ~3800s
- `ES+`: ~4500s
#### Middle Chart (Kernel GCC 6.8.0)
- **Trend**: Build duration peaks at `ES+` but shows minor fluctuations.
- **Values**:
- `H`: ~200s
- `HS`: ~250s
- `E`: ~220s
- `ES`: ~270s
- `ES+`: ~500s
#### Right Chart (Kernel Clang 6.8.0)
- **Trend**: Build duration increases steadily, with `ES+` significantly higher than others.
- **Values**:
- `H`: ~400s
- `HS`: ~420s
- `E`: ~450s
- `ES`: ~470s
- `ES+`: ~700s
---
### Key Observations
1. **Compiler Impact**:
- Clang (18.1.3) exhibits **~10x longer build times** than GCC (6.8.0) and **~2x longer** than Clang (6.8.0).
- Kernel Clang (6.8.0) shows the smallest build durations overall.
2. **Configuration Impact**:
- `ES+` consistently requires the longest build time across all charts.
- In the GCC chart, `ES+` is **~1.8x longer** than `H`, while in Clang charts, the multiplier is **~1.8x (GCC)** and **~1.6x (Clang 18.1.3)**.
3. **Error Bars**:
- Variability is smallest in the GCC chart (e.g., `H` ±10s) and largest in Clang 18.1.3 (`ES+` ±50s).
---
### Interpretation
- **Compiler Versioning**: The stark difference between Clang 18.1.3 and Clang 6.8.0 suggests significant optimizations or architectural changes in the newer version.
- **Configuration Complexity**: The `ES+` configuration (likely "Enhanced Security+") correlates with longer build times, possibly due to additional security checks or code generation overhead.
- **Toolchain Synergy**: GCC (6.8.0) paired with Kernel shows the fastest builds, indicating potential optimizations in this combination. Conversely, Clang 18.1.3’s slower performance might reflect stricter compile-time validations or less efficient code generation for the tested configurations.
No anomalies detected; trends align with expected scaling based on configuration complexity and compiler maturity.
</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
## Flowchart: Artifact Verification and Build Process
### Overview
This flowchart illustrates a multi-stage process for verifying and building software artifacts, emphasizing trust boundaries and execution states. The diagram uses color-coded edges to distinguish between trusted, untrusted, and secure network paths, with a focus on secure commit verification and sandboxed execution.
### Components/Axes
**Nodes (Entities):**
- **A (Artifact Author)**: Initiates the process by committing code.
- **B (Verifier)**: Validates code integrity using PCR0 (Platform Configuration Register).
- **C (RHP)**: Receives initial build instructions and code.
- **D (Build Server)**: Executes code builds and attests to commit hashes.
- **E (Enclave)**: Secure environment for commit verification and artifact retrieval.
- **F (Sandbox)**: Untrusted execution environment for code.
- **G (Log)**: Records system events and attestations.
**Edges (Flow/Relationships):**
- **Red Dashed Lines**: Untrusted network paths (e.g., adversary interactions).
- **Green Lines**: Trusted network paths (secure communication).
- **Black Lines**: Secure network paths (enclave-to-trusted network).
- **Dotted Red Lines**: Untrusted execution state transitions.
**Legend (Right Side):**
- **Adversary Network**: Red dashed lines.
- **Trusted Network**: Green lines.
- **Secure Network**: Black lines.
- **Untrusted Execution State**: Dotted red lines.
### Detailed Analysis
1. **Step 1**: Artifact Author (`A`) commits code (`Commit_A(code)`).
2. **Step 11**: Verifier (`B`) validates the commit using PCR0 (`Verify(ip,pcr0)`), creating a feedback loop to ensure integrity.
3. **Steps 2-3**: RHP (`C`) initializes build images (`InitImage(pcr0)`) and code (`InitBuild(code)`).
4. **Step 4**: Enclave (`E`) verifies commit hashes (`VerifyCommit(h(code))`) and secures them (`SecureCommit(h(code))`).
5. **Step 6**: Build Server (`D`) compiles code (`Build(code)`) and sends artifact hashes (`SendHash(h(artifact))`).
6. **Steps 8-9**: Build Server attests to commit hashes (`Attestation(commit, h(artifact), pcr0)`) and logs entries (`LogEntry(...)`).
7. **Step 10**: Enclave retrieves artifacts (`Get(artifact, at, ip)`).
8. **Flow to Sandbox/Log**:
- Untrusted code flows to Sandbox (`F`) via dotted red lines.
- Log entries (`G`) are secured via black lines to the Trusted Network.
### Key Observations
- **Trust Boundaries**:
- The Enclave (`E`) acts as a secure intermediary between untrusted and trusted networks.
- Adversary Network (`F`) is isolated via red dashed lines, preventing direct access to secure components.
- **Execution States**:
- Code transitions to an "Untrusted Execution State" (dotted red) before sandbox execution.
- SecureCommit (`E`) ensures hashes are cryptographically protected before network transmission.
- **Feedback Loops**:
- Verifier (`B`) continuously validates PCR0, creating a self-correcting integrity check.
### Interpretation
This diagram models a **secure software supply chain** with layered trust assumptions:
1. **Author Trust**: Code is initially untrusted but validated by the Verifier (`B`) using hardware-backed PCR0.
2. **Build Integrity**: The Build Server (`D`) and Enclave (`E`) collaborate to ensure code authenticity via attestations and secure hashing.
3. **Execution Isolation**: Untrusted code is sandboxed (`F`), while logs (`G`) remain in the Trusted Network to prevent tampering.
4. **Adversary Mitigation**: Red dashed lines represent potential attack vectors, emphasizing the need for enclave-based verification to prevent compromise.
The process highlights a **zero-trust architecture** where trust is earned through cryptographic proofs (e.g., PCR0, commit hashes) rather than implicit trust in network paths. The Enclave (`E`) serves as the critical trust anchor, ensuring secure execution and attestation even in untrusted environments.
</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 $∃\ 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 $∀\ 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 $∃\ 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 $∀\ 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 $∃\ 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 $∀\ 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 $∃\ 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 $∀\ 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
## Flowchart: Debian Package Build Process
### Overview
The diagram illustrates a technical workflow for building a Debian package (.deb) from source code. It depicts four key stages connected by directional arrows, with a maintainer interacting with the process via a laptop.
### Components/Axes
1. **Source** (Top-left):
- Icon: Document with `<//>` code symbols
- Label: "Source"
- Connection: Rightward arrow to `.tar.gz`
2. **.tar.gz** (Center-left):
- Icon: Cube
- Label: ".tar.gz"
- Connection: Rightward arrow to "Packager"
3. **Packager** (Center-right):
- Icon: Gear overlapping cloud
- Label: "Packager"
- Connection: Rightward arrow to `.deb`
4. **.deb** (Top-right):
- Icon: Black cube
- Label: ".deb"
5. **Maintainer** (Bottom-center):
- Icon: Laptop
- Label: "Maintainer"
- Connection: Downward arrow to "Source"
### Detailed Analysis
- **Source → .tar.gz**: The maintainer's laptop (Maintainer) interacts with the source code, which is then archived into a `.tar.gz` tarball.
- **.tar.gz → Packager**: The tarball is processed by the Packager component, represented by a gear (automation) and cloud (cloud-based processing).
- **Packager → .deb**: The Packager generates the final Debian package (`.deb`), symbolized by a black cube.
### Key Observations
- The maintainer's role is explicitly tied to the initial source code stage.
- The Packager stage combines automation (gear) and cloud infrastructure, suggesting distributed processing.
- No numerical data or quantitative metrics are present; the diagram focuses on process flow.
### Interpretation
This flowchart represents a simplified Debian package build pipeline:
1. **Source Preparation**: Maintainers use their laptops to prepare and modify source code.
2. **Tarball Creation**: Code is packaged into a `.tar.gz` archive for distribution.
3. **Automated Packaging**: The Packager stage likely involves build automation tools (e.g., `debuild`, `dpkg-buildpackage`) and cloud resources for compilation.
4. **Final Output**: The process culminates in a Debian package (`.deb`), ready for distribution in repositories.
The diagram emphasizes the separation of human intervention (Maintainer) from automated build processes (Packager), highlighting the role of cloud infrastructure in modern package management workflows.
</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 Workflow for Project TinyCC
### Overview
The image shows a GitHub Actions workflow interface for a project named "Project TinyCC" (ID: #54). The workflow is in the "CI Build" job, which succeeded 18 hours ago. The interface includes a left-side summary panel and a right-side detailed log panel. The logs contain technical commands, timestamps, and outputs related to the build process.
---
### Components/Axes
#### Left Panel (Summary)
- **Tabs**: Jobs, Run details, Usage, Workflow file
- **Labels**:
- "CI Build" (selected)
- "Current runner version: 12.321.0"
- "Runner name: 'Nitroloris'"
- "Runner group name: 'default'"
- "Machine name: 'sandbox'"
- "Secret source: Actions"
- "Prepare workflow directory"
- "Prepare all required actions"
- "Complete job name: CI Build"
#### Right Panel (Logs)
- **Sections**:
1. **Setup job** (timestamp: 18 hours ago)
- Commands: `gcc -c tcc.c`, `make`, `Run attestation`
- Outputs: `tcc.o`, `tcc`, `attestation results`
2. **Run** (timestamp: 18 hours ago)
- Commands: `gcc -c tcc.c`, `make`, `Run attestation`
- Outputs: `tcc.o`, `tcc`, `attestation results`
3. **Run attestation** (timestamp: 18 hours ago)
- Commands: `Run attestation`, `Run attestation`
- Outputs: `Attestation results`, `Artifact hashes`, `PCR values`
---
### Detailed Analysis
#### Left Panel (Summary)
- **Tabs**:
- **Jobs**: Displays the "CI Build" job status (succeeded).
- **Run details**: Includes runner version, runner name, and machine name.
- **Usage**: Not explicitly detailed in the image.
- **Workflow file**: Not visible in the image.
#### Right Panel (Logs)
- **Setup job**:
- **Commands**:
1. `gcc -c tcc.c` (compiles `tcc.c` to `tcc.o`)
2. `make` (builds the project)
3. `Run attestation` (executes attestation process)
- **Outputs**:
- `tcc.o` (object file)
- `tcc` (executable)
- `Attestation results` (hashes and PCR values)
- **Run**:
- Repeats the same commands as "Setup job" with identical outputs.
- **Run attestation**:
- **Commands**:
- `Run attestation` (executes the attestation process)
- **Outputs**:
- `Attestation results` (e.g., `commit_hash`, `artifact_hash`, `PCR values`).
- Example PCR values: `pcr7: "0x1010000000000000000000000000000000000000000000000000000000000000"`.
---
### Key Observations
1. **Build Success**: The "CI Build" job succeeded, indicating the project compiled without errors.
2. **Attestation Process**: The `Run attestation` command generates cryptographic hashes and PCR values, ensuring the build environment's integrity.
3. **Repetition**: The "Run" and "Run attestation" sections repeat the same commands and outputs, suggesting a multi-stage verification process.
4. **Timestamp Consistency**: All sections are timestamped 18 hours ago, indicating the workflow completed in a single run.
---
### Interpretation
This workflow demonstrates a CI/CD pipeline for "Project TinyCC," a C compiler. The `Run attestation` step ensures the build environment is secure and unaltered by generating cryptographic evidence (e.g., PCR values). The repetition of commands across sections suggests a focus on redundancy and verification. The success of the build and attestation confirms the project's code integrity and adherence to security standards. The use of `gcc` and `make` indicates a traditional C compilation workflow, while the attestation process adds a layer of trust for downstream users or systems.
</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
## Flowchart: Secure Commit Process Workflow
### Overview
The image contains two interconnected diagrams illustrating a secure commit process workflow in software development. The diagrams use code references (e.g., `$B1`, `$E1`, `$A1`), component labels (e.g., "StartBuild(AR1)"), and directional arrows to depict the flow of operations. The left diagram focuses on initial stages, while the right diagram expands to include attestation, log entry, and broader infrastructure interactions.
---
### Components/Axes
#### Key Components (Left Diagram):
1. **StartBuild(AR1)**
- Code references: `$B1`, `$E1`, `$A1`
- Action: `int.build_infrastructure(initBuild(artifact))`
2. **CreateSecureCommit**
- Code references: `$B4`, `$E4`, `$A4`
- Action: `int.build_infrastructure(initBuild(artifact))`
3. **ProvideAttestation(AR2)**
- Code references: `$B2`, `$E2`, `$A2`
- Action: `int.build_infrastructure(initBuild(artifact))`
4. **CreateSecureCommit (Secondary)**
- Code references: `$B3`, `$E3`, `$A3`
- Action: `int.build_infrastructure(initBuild(artifact))`
#### Key Components (Right Diagram):
1. **StartBuild(AR1)**
- Code references: `$B1`, `$E1`, `$A1`
- Action: `int.build_infrastructure(initBuild(artifact))`
2. **CreateSecureCommit**
- Code references: `$B4`, `$E4`, `$A4`
- Action: `int.build_infrastructure(initBuild(artifact))`
3. **ProvideAttestation(AR2)**
- Code references: `$B2`, `$E2`, `$A2`
- Action: `int.build_infrastructure(initBuild(artifact))`
4. **ProvideLogEntry(H1)**
- Code references: `$B5`, `$E5`, `$A5`
- Action: `int.build_infrastructure(initBuild(artifact))`
5. **CreateSecureCommit (Secondary)**
- Code references: `$B3`, `$E3`, `$A3`
- Action: `int.build_infrastructure(initBuild(artifact))`
6. **ProvideAttestation(AR3)**
- Code references: `$B6`, `$E6`, `$A6`
- Action: `int.build_infrastructure(initBuild(artifact))`
#### Arrows and Flow:
- Arrows indicate sequential or conditional execution (e.g., `→`, `→→`).
- Dashed arrows (`→→→`) suggest optional or parallel paths.
---
### Detailed Analysis
#### Left Diagram:
1. **StartBuild(AR1)** → **CreateSecureCommit** → **ProvideAttestation(AR2)**
- Initial build infrastructure setup (`$B1`, `$E1`, `$A1`).
- Secure commit process (`$B4`, `$E4`, `$A4`).
- Attestation generation (`$B2`, `$E2`, `$A2`).
2. **CreateSecureCommit (Secondary)** → **StartBuild(AR1)**
- Feedback loop for re-initialization.
#### Right Diagram:
1. **StartBuild(AR1)** → **CreateSecureCommit** → **ProvideAttestation(AR2)**
- Core workflow with attestation.
2. **CreateSecureCommit** → **ProvideLogEntry(H1)**
- Logging of commit events (`$B5`, `$E5`, `$A5`).
3. **ProvideAttestation(AR2)** → **CreateSecureCommit (Secondary)**
- Attestation validation triggers secondary commit.
4. **CreateSecureCommit (Secondary)** → **ProvideAttestation(AR3)**
- Expanded attestation for additional stages (`$B6`, `$E6`, `$A6`).
---
### Key Observations
1. **Code References**:
- `$B1`, `$E1`, `$A1` consistently appear in initial build steps.
- `$B4`, `$E4`, `$A4` dominate secure commit operations.
- `$B2`, `$E2`, `$A2` are tied to attestation.
2. **Flow Complexity**:
- The right diagram introduces branching (e.g., attestation → secondary commit).
- Dashed arrows suggest optional steps (e.g., log entry).
3. **Component Isolation**:
- Left diagram focuses on core commit and attestation.
- Right diagram adds logging and expanded attestation.
---
### Interpretation
1. **Purpose**:
- The diagrams model a secure commit workflow with emphasis on infrastructure validation (`int.build_infrastructure`), attestation, and logging.
2. **Relationships**:
- Attestation (`ProvideAttestation`) acts as a gatekeeper for subsequent commits.
- Logging (`ProvideLogEntry`) ensures auditability.
3. **Notable Patterns**:
- Repetition of `int.build_infrastructure` suggests modularity in infrastructure setup.
- Secondary commit steps imply iterative validation.
4. **Anomalies**:
- No explicit error-handling paths are depicted.
- The right diagram’s complexity may indicate scalability challenges.
---
**Note**: No numerical data or legends are present. All textual elements are transcribed directly from the diagrams.
</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
## Bar Chart: Build Time Comparison Across Configurations and Environments
### Overview
The image is a grouped bar chart comparing the overall duration (in seconds) of build processes across three configurations: **Clang (18.1.3)**, **Kernel (6.8.0, gcc)**, and **Kernel (6.8.0, clang)**. Each configuration is further divided into five subcategories: **H**, **HS**, **E**, **ES**, and **ES+**. The chart uses stacked bars to break down the total duration into five components: **Start EIF**, **Runner init**, **Configure**, **Checkout**, and **Build**.
---
### Components/Axes
- **X-Axis**:
- Labels: `H`, `HS`, `E`, `ES`, `ES+` (repeated for each configuration).
- Categories: Three main groups (`Clang`, `Kernel (gcc)`, `Kernel (clang)`), each with five subcategories.
- **Y-Axis**:
- Label: `Overall duration (s)`.
- Scale: 0 to 5000 (linear increments of 1000).
- **Legend**:
- Colors and labels:
- **Blue**: Start EIF
- **Orange**: Runner init
- **Light Green**: Configure
- **Orange**: Checkout (conflict with Runner init)
- **Dark Green**: Build
---
### Detailed Analysis
#### Clang (18.1.3)
- **H**:
- Total: ~3000s
- Build: ~3000s (dark green)
- Checkout: ~200s (orange)
- Configure: ~100s (light green)
- Runner init: ~50s (orange)
- Start EIF: ~20s (blue)
- **HS**:
- Total: ~3400s
- Build: ~3400s (dark green)
- Checkout: ~250s (orange)
- Configure: ~150s (light green)
- Runner init: ~75s (orange)
- Start EIF: ~30s (blue)
- **E**:
- Total: ~3500s
- Build: ~3500s (dark green)
- Checkout: ~300s (orange)
- Configure: ~200s (light green)
- Runner init: ~100s (orange)
- Start EIF: ~50s (blue)
- **ES**:
- Total: ~4000s
- Build: ~4000s (dark green)
- Checkout: ~350s (orange)
- Configure: ~250s (light green)
- Runner init: ~150s (orange)
- Start EIF: ~75s (blue)
- **ES+**:
- Total: ~5000s
- Build: ~5000s (dark green)
- Checkout: ~400s (orange)
- Configure: ~300s (light green)
- Runner init: ~200s (orange)
- Start EIF: ~100s (blue)
#### Kernel (6.8.0, gcc)
- **H**:
- Total: ~400s
- Build: ~300s (dark green)
- Checkout: ~80s (orange)
- Configure: ~20s (light green)
- Runner init: ~50s (orange)
- Start EIF: ~10s (blue)
- **HS**:
- Total: ~500s
- Build: ~400s (dark green)
- Checkout: ~100s (orange)
- Configure: ~30s (light green)
- Runner init: ~60s (orange)
- Start EIF: ~20s (blue)
- **E**:
- Total: ~600s
- Build: ~500s (dark green)
- Checkout: ~120s (orange)
- Configure: ~40s (light green)
- Runner init: ~70s (orange)
- Start EIF: ~30s (blue)
- **ES**:
- Total: ~700s
- Build: ~600s (dark green)
- Checkout: ~150s (orange)
- Configure: ~50s (light green)
- Runner init: ~80s (orange)
- Start EIF: ~40s (blue)
- **ES+**:
- Total: ~800s
- Build: ~700s (dark green)
- Checkout: ~200s (orange)
- Configure: ~60s (light green)
- Runner init: ~100s (orange)
- Start EIF: ~50s (blue)
#### Kernel (6.8.0, clang)
- **H**:
- Total: ~500s
- Build: ~400s (dark green)
- Checkout: ~90s (orange)
- Configure: ~25s (light green)
- Runner init: ~55s (orange)
- Start EIF: ~15s (blue)
- **HS**:
- Total: ~600s
- Build: ~500s (dark green)
- Checkout: ~110s (orange)
- Configure: ~35s (light green)
- Runner init: ~65s (orange)
- Start EIF: ~25s (blue)
- **E**:
- Total: ~700s
- Build: ~600s (dark green)
- Checkout: ~130s (orange)
- Configure: ~45s (light green)
- Runner init: ~75s (orange)
- Start EIF: ~35s (blue)
- **ES**:
- Total: ~800s
- Build: ~700s (dark green)
- Checkout: ~160s (orange)
- Configure: ~55s (light green)
- Runner init: ~85s (orange)
- Start EIF: ~45s (blue)
- **ES+**:
- Total: ~900s
- Build: ~800s (dark green)
- Checkout: ~210s (orange)
- Configure: ~70s (light green)
- Runner init: ~110s (orange)
- Start EIF: ~55s (blue)
---
### Key Observations
1. **Clang Dominates Build Times**:
- Clang configurations (18.1.3) have significantly longer total durations (3000–5000s) compared to Kernel configurations (400–900s).
- The **Build** phase (dark green) accounts for ~90% of the total time in Clang, while Kernel configurations show a more balanced distribution (Build: 50–80%).
2. **Component Contributions**:
- **Checkout** (orange) and **Runner init** (orange) are visually indistinguishable due to shared color, causing potential misinterpretation.
- **Start EIF** (blue) is the smallest contributor across all configurations.
3. **Environmental Impact**:
- **ES+** configurations consistently show the longest durations, suggesting increased complexity or resource demands.
- **H** configurations are the fastest in all cases.
---
### Interpretation
- **Clang vs. Kernel**: The stark difference in build times highlights Clang's inefficiency compared to Kernel, possibly due to compiler optimizations or environment setup.
- **Color Legend Conflict**: The overlapping orange labels for **Runner init** and **Checkout** risk misrepresenting their contributions. This could lead to incorrect assumptions about phase durations.
- **ES+ Anomaly**: The exponential growth in ES+ durations (e.g., Clang: 3000s → 5000s) suggests non-linear scaling, warranting investigation into resource bottlenecks or configuration overhead.
The data underscores the need for optimization in Clang's build process, particularly in the **Build** phase, and clarifies the legend to avoid ambiguity in component analysis.
</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
## Bar Chart: Overall Duration (s) of Software Tools Across Environments
### Overview
The chart is a grouped bar chart comparing the **overall duration (in seconds)** of various software tools across three environments: **HS**, **ES**, and **ES+**. Each tool has three bars (one per environment), with colors corresponding to a legend that maps colors to specific components (e.g., Start EIF, Boot, etc.). The y-axis ranges from 0 to 500 seconds, and the x-axis lists software tools with their version numbers.
---
### Components/Axes
- **X-axis**: Software tools (e.g., GProlog, Hello, IPXE, etc.) with version numbers in parentheses.
- **Y-axis**: "Overall duration (s)" with a scale from 0 to 500.
- **Legend**: Located at the bottom, mapping colors to components:
- **Blue**: Start EIF
- **Light Blue**: Boot
- **Orange**: Runner init
- **Light Orange**: Checkout
- **Green**: Configure
- **Dark Green**: Build
---
### Detailed Analysis
#### Key Data Points and Trends
1. **NeoVIM (0.11.0)**:
- **ES+**: Tallest bar (~490s), indicating the longest overall duration.
- **ES**: ~280s.
- **HS**: ~120s.
- **Trend**: Duration increases significantly with environment complexity (HS < ES < ES+).
2. **LibSodium (1.0.20)**:
- **ES+**: ~380s (second-tallest).
- **ES**: ~180s.
- **HS**: ~60s.
- **Trend**: Similar to NeoVIM, with a steep increase in ES+.
3. **IPXE (1.21.1)**:
- **HS**: Shortest bar (~30s).
- **ES**: ~50s.
- **ES+**: ~70s.
- **Trend**: Minimal variation across environments.
4. **Other Tools**:
- **GProlog (1.6.0)**: ~80s (HS), ~120s (ES), ~150s (ES+).
- **Hello (2.10)**: ~90s (HS), ~130s (ES), ~160s (ES+).
- **Scheme48 (1.9.3)**: ~70s (HS), ~110s (ES), ~140s (ES+).
- **TinyCC (0.9.28)**: ~40s (HS), ~60s (ES), ~80s (ES+).
- **Verifier Client**: ~100s (HS), ~140s (ES), ~170s (ES+).
- **XZ Utils (5.6.3)**: ~50s (HS), ~80s (ES), ~110s (ES+).
#### Color Mapping and Legend
- **HS**: Blue (Start EIF)
- **ES**: Light Blue (Boot)
- **ES+**: Orange (Runner init)
- **Note**: The legend’s colors (e.g., green for Configure) do not directly map to the environment bars, suggesting the chart may represent **total duration** rather than component breakdowns.
---
### Key Observations
1. **Environmental Impact**:
- **ES+** consistently shows the longest durations, likely due to increased complexity or resource usage.
- **HS** (simplest environment) has the shortest durations for most tools.
2. **Outliers**:
- **NeoVIM** in **ES+** is the slowest tool (~490s), far exceeding others.
- **IPXE** in **HS** is the fastest (~30s), significantly lower than other tools.
3. **Color Consistency**:
- The legend’s colors (e.g., green for Configure) do not align with the environment bars, indicating a potential mismatch or mislabeling.
---
### Interpretation
The chart highlights how **environment complexity** (HS < ES < ES+) correlates with **execution time** for software tools. Tools like **NeoVIM** and **LibSodium** are particularly sensitive to environment changes, while **IPXE** remains efficient across all environments. The legend’s color mapping appears inconsistent with the chart’s data, suggesting a possible error in labeling or a misinterpretation of the chart’s purpose. This discrepancy could lead to confusion in analyzing component-specific durations (e.g., Start EIF vs. Build).
The data underscores the importance of environment optimization for performance-critical tools, with **ES+** requiring further investigation to address inefficiencies.
</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}$ | |