Building Honest Systems with Rust, WebAssembly, and Confidential Computing

Technology | Published on August 7, 2025

Discover key insights from our recent presentation, where we share our hands-on experience using Rust and WebAssembly in a production environment.

Building Honest Systems with Rust, WebAssembly, and Confidential Computing 

In June, we had the opportunity to present our use of Rust and WebAssembly (Wasm) in contained environments at the Rust Paris 2025 conference, organised by Systematic. This article covers our presentation and shares our experience using Rust and Wasm in production. 

From the beginning, our mission at Secretarium has been to protect privacy, data, and code, and to make information systems safer, more honest, and sovereign. We are experts in Confidential Computing, a technology that guarantees data security even during processing through Trusted Execution Environments (TEEs). We design what we call "honest systems," which are distinguished by their ability to permanently and verifiably guarantee the integrity and confidentiality of code and data. In this article, we'll explain our technology stack and why Rust and WebAssembly (Wasm) play an essential role in securing and adopting honest systems from the cloud to the edge. 

What is an Honest System? 

First, it's important to explain what an honest system is and its role in the industry. Put simply, an honest system is one that cannot lie about the management, processing, and security of the data it handles. These systems are tamper-proof, immutable, and protect the integrity and confidentiality of data at all times: at rest, in transit, and during processing. 

Another key aspect is transparency. If we have to "trust" the system, it contradicts the objective. For this reason, it's important that these systems are "trustless." They must be verifiable and transparent at all times. For a more detailed description of the honest system concept, we invite you to read the following research paper that we co-authored with Imperial College London: https://doi.org/10.1017/dap.2024.68

In the industry, these systems are used for several reasons, and at Secretarium, we help developers and our clients, primarily governments and large companies that handle massive volumes of sensitive data, to use their data without ever exposing it. Our main use cases are: 

  • Secure collaboration on sensitive data: In areas like anti-money laundering, it's crucial to cross-reference data between parties (e.g. banks) without actually sharing it. Our solutions enable collective data analysis while preserving confidentiality. 
  • Protection against internal and external threats: For companies handling critical data (sensitive applications, health, etc), our technology helps secure data, even against the cloud provider or the employees themselves. 
  • Regulatory compliance and auditability: We make it possible to prove compliance with regulations while ensuring confidentiality, thanks to immutable and tamper-proof systems. 
  • Security applied to AI: Whether it's to protect models, guarantee confidential inference, or use sensitive data for RAG, our approach helps secure code, models, and data at every stage. 

RoT and TCB: The Foundations of an Honest System 

An honest system is based on two essential pillars: the Root of Trust (RoT) and the Trusted Computing Base (TCB). In a modern software stack, the application you develop relies on entire layers of infrastructure: software, operating system, hypervisor, firmware, hardware, etc. Each of these layers must be implicitly trustworthy to ensure your application works correctly. Unfortunately, the more intermediaries you have to trust, the more fragile the system becomes and the further it moves from "trustless" ideals. If just one of these layers is compromised or misconfigured, the entire chain suffers. 

Reducing the TCB to the Bare Essentials 

The goal here is clear: to minimise the TCB as much as possible. This is the perimeter of code and components on which the system's trust relies. Ideally, you want only your application and the data it processes to be part of this trusted base. Everything else must be considered untrustworthy by default. 

Klave Diagrams-28.png

Figure 1 - Target TCB 

A Unique and Clear Root of Trust 

This is where the concept of the Root of Trust comes in: an initial anchor of trust in the system that everything else can build upon. This root can be hardware (like a TPM module or a secure enclave), software, or even cloud-based depending on the use case. The ideal is a single, clearly defined Root of Trust, located at the hardware level, to build a chain of trust from the lowest level all the way to your application. 

Confidential Computing as the Technological Base 

The good news is that technologies that reduce the TCB, define a solid RoT, and ensure data remains protected at all times are no longer utopian. This is largely thanks to Confidential Computing, with technologies like hardware enclaves and confidential VMs, or approaches based on deterministic and verifiable systems. At Secretarium, we have a hybrid approach based on Confidential Computing but also on distributed ledger technologies for computational integrity, immutability, and data verifiability. 

We have been working with Intel since 2016 on their Software Guard Extension (SGX) technology. Intel SGX is a Trusted Execution Environment (TEE) technology, hardware security integrated into the processor that encrypts the memory where the workload runs. The principle is that when the processor is manufactured, a key pair is generated by Intel. The private key is physically "etched" into the processor, then erased, and only the public key is kept by Intel. This allows for communication with the processor in a way similar to a TLS connection and also for attestation, using an Intel service, that the code is indeed running within an authentic enclave. We call this a secure enclave. In addition to guaranteeing execution confidentiality, this also protects the integrity of the workload, the code and data, during use. 

There are several "flavours" of Confidential Computing, with different technologies and attack surfaces (confidential VMs: Intel TDX, AMD SEV, or application isolation: Intel SGX). The one we're interested in here is the one with the smallest possible TCB. The threat model of this type of TEE (here, Intel SGX) is extremely robust, especially against internal actors or cloud providers. A cloud operator or an internal administrator, even with root access to the machines, will have no way to read memory or access the data. 

Klave Diagrams-31 1.png

Figure 2 - Confidential Computing TCB 

From a Monolithic Architecture to a Multi-tenant Platform 

At Secretarium, we built a platform (Klave) where we develop solutions for our clients, and which is also open to all developers who want to create honest applications: https://klave.com

Our architecture is based on three key elements: a cluster of TEEs (Intel SGX), a consensus algorithm (BFT-RAFT) for computational integrity, and a distributed ledger that guarantees data confidentiality, immutability, and verifiability. 

Our original version, compatible with the Intel SGX SDK in C/C++, was entirely developed in C++, including the application logic. This technical choice proved relevant for specific solutions but quickly showed its limitations in terms of scalability and accessibility. 

Figure 3

Figure 3 – Original Architecture 

Building the business logic for a client application isn't easy. It involves mastering a low-level C++ SDK, which limits adoption. This complexity makes the technology difficult for most of our clients to access. 

Moreover, this architecture is not very flexible. With each new client application version deployed, the entire enclave has to be restarted, which leads to slow startup times and service interruptions. 

Finally, the cluster couldn't be reused for other clients because there was no simple mechanism for multi-tenancy. In short: one application per enclave. So, we had to rethink our architecture. 

Wasm and Rust for Flexibility and Security 

In our current architecture, we addressed the performance and multi-tenancy limitations by supporting WebAssembly and introducing a Wasm runtime in the enclaves. 

Figure 4

Figure 4 - Current Architecture 

WebAssembly is a portable binary format, initially designed for the browser, but which is now also becoming a standard on the server side. It allows compiled code to be executed in an isolated, fast, and secure environment, regardless of the source language (Rust, C/C++, Go, etc.). Think of it as Java, but on steroids. 

Wasm allows us to avoid enclave restarts and cold starts during application deployments while maintaining near-native performance. It is also more accessible because developers can use the language of their choice (no more C++ only). This also makes a secure multi-tenants' architecture possible, thanks to Wasm's isolation guarantees.  

This is where Rust comes in, at several levels: in secure enclaves, cohabiting with C++, but also on the client side, with applications developed in Rust and compiled to Wasm. Rust's memory safety guarantees, its compatibility with C++, and its native Wasm support allow us to run native Rust code inside the WebAssembly runtime, all while benefiting from enhanced security compared to applications written only in C++. 

Integrating a Wasm Runtime 

Leveraging Wasm will allow us to manage multi-tenancy of several applications within a single enclave, thus reducing fixed enclave costs, both in terms of memory and startup time. Furthermore, with Wasm, application developers can continue to use their preferred languages, as long as they can compile to Wasm bytecode, greatly improving accessibility. 

Let's clarify some terms: the Wasm runtime is the execution environment within which Wasm applications run; an "enclave" is the SGX-protected execution environment that hosts the Wasm runtime; and the "host" is the process responsible for managing enclave lifecycles and exposing system functions to them. 

MVP: WebAssembly Micro Runtime (WAMR) 

There are many Wasm runtimes. We initially chose WAMR (https://github.com/bytecodealliance/wasm-micro-runtime), written in C, which directly offers a compilation configuration for SGX. It uses Intel's SDK, which is also what we use to build the core of our enclaves, written in C++. Integration was therefore simple, mainly managing compilation via CMake within our CI pipeline, without needing code modification due to execution in an enclave. However, there were two important limitations to using WAMR (as the word "micro" suggests). 

  1. WAMR doesn't support the Component Model. The Component Model adds metadata to a Wasm module describing its interface, using a powerful type system exposed via the WIT (WebAssembly Interface Types) language. This greatly facilitates application creation by allowing Wasm modules to be composed through these interfaces. Unfortunately, WAMR's minimalist approach does not offer Component Model support. 
  2. WAMR has no notion of "fuel." It's important to be able to measure and control the CPU consumption of applications. This is partly to manage billing when you offer a platform for hosting applications, but also and perhaps more importantly, to protect the platform itself. Whether due to a programming error or malice, it would be easy, for example, to enter an infinite loop that would block at least one CPU core, or even the entire platform if it's a transaction being executed (the transaction log is a chain, and therefore necessarily sequential). The solution is to measure consumption during execution and, if necessary, interrupt a process if the "fuel" initially allocated to it runs out. Since WAMR offered nothing of the sort, we added it, but it was much easier to do at the Wasm interpreter level than at the AOT compiler level (both exist in WAMR). Naturally, using the interpreter has a significant impact on performance, by a factor of 10 or 15. 

Migration to Wasmtime 

We therefore decided to migrate to another Wasm runtime: Wasmtime (https://github.com/bytecodealliance/wasmtime). Wasmtime is written in Rust, and the project is actively developed. This is often where new Wasm features are initially implemented, and in particular, the Component Model is a first-class citizen. The notion of "fuel" is also present, even with AOT compilation. The two main limitations of WAMR are thus addressed, and we also benefit from the advantages of the Rust language, particularly the memory and concurrency safety guarantees, with performance comparable to C/C++, while allowing for easy integration with the rest of our C++ codebase. 

Using Rust in an SGX Enclave 

The code running in an enclave is constrained. In particular, it cannot make direct system calls; these must go through the host, which only exposes a subset of them. Additionally, certain operations require SGX-specific API calls such as, managing enclave memory allocation, data sealing, and attestation procedures. 

We wanted to be able to keep our entire C++ enclave infrastructure, which uses the Intel SGX SDK. The basic idea for having Rust in an enclave is to use a specific compilation target, which will provide the necessary library implementations for the enclave environment (since the standard std library cannot be used directly in SGX enclaves). 

Such target exists, for instance x86_64-fortanix-unknown-sgx (https://doc.rust-lang.org/beta/rustc/platform-support/x86_64-fortanix-unknown-sgx.html), which is Tier 2 in supported platforms. Unfortunately, this target is quite specific and assumes the use of a dedicated host. It is therefore not suitable for our use case, where we want to continue to use our host and the software infrastructure that comes with it. 

Another possibility is to use the Teaclave SGX SDK (https://github.com/apache/incubator-teaclave-sgx-sdk), which is built upon the Intel SDK. However, this project is not well-maintained, so we created a fork (https://github.com/klave-network/teaklave) to add compatibility with the most recent versions of the Intel SDK, but also to allow the use of the "full" SDK in the C++ part, which previously caused linking conflicts. 

Wasmtime Integration 

We now have a custom Rust compilation target, x86_64-sgx_sdk-linux-sgx, provided by our Teaklave fork, which allows us to compile Wasmtime. 

Wasmtime supports Linux, Windows, and MacOS platforms by default, but we need something a little different for SGX enclaves. Fortunately, there is also a "custom" platform, where you only need to provide the implementations of a few functions to have a functional runtime. These are the memory management functions (allocation and protection modifications of the memory pages where the compiled Wasm lies to put it into executable memory and exception handling ("trap") via signals and setjmp/longjmp). These functions are quite easy to implement with the Intel SGX SDK, and we can now host the Wasmtime runtime in our enclaves. 

We still need to make our C++ code communicate with Wasmtime. To do this, Wasmtime exposes a C-API, which is what we will use. However, currently, this C-API does not support the Component Model. We have therefore extended this API for that purpose. 

Next Steps: Wasmtime C-API and WASI 

So, we have achieved our goal: we can run Wasm applications in our enclaves, while still leveraging our existing infrastructure. But of course, as always in development, nothing is ever finished or set in stone. 

As for the Wasmtime C-API modifications, the result works as expected, however it represents a lot of code, making the complete Pull Request process complicated to review. It is therefore currently being integrated in the Wasmtime codebase in smaller, more digestible pieces. Furthermore, some features of the Component Model that we need are not yet exposed by the C-API ("resources" for instance). 

Another important aspect of the Wasm ecosystem is WASI (https://github.com/WebAssembly/WASI). WASI is a set of standardised APIs exposing system functions provided by the runtime to Wasm applications. While the system call capabilities we want to expose are a fairly small subset of WASI due to enclave constraints, it would be beneficial to leverage these standardised APIs whenever possible. 

It should also be noted that there is some friction in our CI pipeline and development environment. Teaclave uses unstable features in Rust, so we have to use a nightly version of Rust. Additionally, we use a development environment in the form of a Docker image, and ensuring the right compiler version runs requires some tinkering, as Rust is installed per-user by default while the same image must be used by everyone with their usual user accounts. 

Rust for Wasm Client Applications 

We have seen that one goal of offering a Wasm platform was to be able to use different languages to write applications. Among these languages, Rust is particularly well-suited. 

Wasm is a well-established Rust compilation target. In Rust you can compile directly to Wasm, which is more efficient than for other languages like Python, Javascript, or .Net. In those cases, a runtime or an interpreter (typically written in C) is compiled to Wasm, and then it executes the applications. And of course, the optimisations that the language allows the compiler to perform largely remain valid in the Wasm context, resulting in very good performance of the generated code. 

It should also be noted that the development tools work well, the Rust ecosystem is mature, and in particular, many existing libraries are directly compatible with the Wasm target. 

Defence in Depth 

It's naive to believe that a system can be perfectly safe and secure. But a proven approach is to view security in layers: even if a flaw exists at one level, the other layers remain, making the attackers' task more difficult, possibly to the point of delaying them until the flaw is identified and corrected. 

In the case of our Klave platform, our first layer is the SGX enclave, which, as we have seen, protects the content of the enclave even from a malicious system administrator. Within the enclave, the Wasm runtime adds a layer of isolation: each application runs in its own isolated memory space with bounds-checked access, and the runtime ensures with memory barriers that applications cannot escape their designated memory boundaries or access each other's data. 

Figure 5

Figure 5 - Application isolation 

Finally, when the application is written in Rust, we have the additional security layer of the memory management integrity guarantees offered by the language. It is entirely possible to write a Wasm application in C with a buffer overrun, which could allow access to data that is in principle inaccessible, obviously while remaining within the "sandbox" allocated to the application. All bugs of this type that are impossible in Rust therefore contribute to the overall security of the system. 

The Component Model 

As we have briefly seen, the Component Model (https://component-model.bytecodealliance.org) allows us to go beyond simple Wasm modules. Wasm's primitive types are extremely limited: there are only numeric, integer, and floating-point types. Of course, integers can represent addresses in the application's linear memory, but you must then know exactly what these addresses correspond to in order to communicate with the application (or for the application to use the services offered by the runtime). 

With WIT interfaces, the Component Model offers a rich type system, with strings of course, but also lists, structs, and even algebraic types (variants, the equivalent of Rust enums). From these interfaces, tools can generate bindings for different languages, whether for the implementation skeleton or for making external calls. This provides natural interoperability between languages without needing to agree on a precise in-memory representation, with the associated risks of error. 

The WIT language is strongly inspired by Rust (in particular because Wasmtime is an important part of the Wasm ecosystem, and therefore the Wasmtime developers who contributed to specifying WIT were naturally influenced by their favourite language). The bindings generated for Rust are therefore very natural, even idiomatic, an additional asset for Rust when it comes to writing Wasm applications. 

Here's what using Rust with WIT can look like, with an excerpt of the WIT describing services that the runtime exposes to applications: 

1package klave:sdk;
2
3interface sdk {
4 // Notifications
5 notify: func(msg: string);
6 // Ledger
7 read-ledger: func(table: string, key: list<u8>) -> result<list<u8>, string>;
8 // …
9}


As well as the WIT describing the Wasm application (component): 

1package component:rust-example;
2
3world rust-example {
4 import klave:sdk/sdk;
5 export greet: func(user: string);
6}


And finally, the implementation of the application in Rust: 

1#[allow(warnings)]
2mod bindings;
3
4use bindings::klave::sdk::sdk;
5
6struct Component;
7
8impl Guest for Component {
9 fn greet_user(user: String) {
10 let Ok(city) = sdk::read_ledger("user_city", &user) else {
11 sdk::notify(&format!("Failed to read from ledger: '{user}'"));
12 return;
13 };
14
15 let msg = if city.is_empty() {
16 format!("The key '{user}' was not found in user_city")
17 } else {
18 match String::from_utf8(city) {
19 Ok(city_name) => format!("Hello {user} from city {city_name}"),
20 Err(_) => {
21 sdk::notify(&format!("Invalid UTF-8 data for user '{user}'"));
22 return;
23 }
24 }
25 };
26
27 sdk::notify(&msg);
28 }
29}
30
31bindings::export! (Component with_types_in bindings);
32


We can see that the implementation is completely idiomatic, in particular the way of handling calls that may potentially fail. 

Observed Points of Attention 

We have seen that Rust is very suitable for writing Wasm applications. But not everything is necessarily idyllic! The flip side of the ease of using existing libraries is that you can quickly generate fairly large Wasm modules. They will be more expensive to store on the platform and, above all, will take longer to compile from Wasm to native. 

It's possible to use Rust for simple Wasm modules without using the Component Model, but communication with the runtime becomes more complex. However, this challenge is not particularly specific to Rust. 

In addition, reproducible builds are not easy to achieve. This is particularly important for Klave, where we aim to cryptographically prove that the code being executed is exactly what is expected. Ideally, one should be able to compile source code independently and verify the hash of the resulting Wasm. However, with the Rust toolchain, even when compilation is technically reproducible, this is only true under identical conditions. In particular, the file path must be the same, and all dependency and compiler/toolchain versions must match exactly. 

Conclusion: An Architecture Ready for the Future 

Rust and Wasm are now technological pillars of our architecture. With the safety, performance, and ergonomics of Rust, combined with the portability, isolation, and efficiency of Wasm, we have a universal, scalable, and powerful foundation for building honest systems. 

It is true that the Wasm Component Model and WASI are still young proposals, but they lay the foundations for a modular, standardised, and interoperable ecosystem. We are now focusing our efforts on their integration to offer developers an ever more fluid, safe, and powerful experience. 

With the growing industry interest in sovereign solutions and the essential need for secure use of sensitive data, our approach makes it possible to extend these guarantees from the cloud to the edge, without compromising on security or performance. Mature technologies like Intel SGX for the cloud and ARM TrustZone for the edge make this possible today. 

If you’re interested in deploying your first application on Klave, please visit: https://docs.klave.com/quickstart/create


Written by Étienne Bossé (Head of Platform) and Jean-Jacques Lafay (Senior Software Engineer) at Secretarium.

Read next

We actively engage in highly innovative projects. Explore our latest publications featuring our cutting-edge technology.

Honest systems article
Technology

Building Honest Systems with Rust, WebAssembly, and Confidential Computing

Discover key insights from our recent presentation, where we share our hands-on experience using Rust and WebAssembly in a production environment.

AI Outcomes
Technology

Improving AI Outcomes with Private RAGs

Learn how leveraging private data in RAG architectures enhances AI performance while maintaining data confidentiality.

TEE Attestation
Technology

Trusted Execution Environments (TEEs) Attestation Management with the Klave SDK

TEE Attestation Management made easy for developers, using the Klave SDK.

PvP
Technology

Secure Payment vs. Payment: Introducing the Klave PvP Orchestrator Template

Our new EVM Payment vs Payment template is a Rust-based orchestrator for creating on-chain PVP or PVD interactions across multiple EVM-compatible blockchains.

EVM Wallet
Technology

Securely Manage Your Assets: Introducing the Klave EVM Wallet Template

Sharing our latest template, a Rust-based wallet for secure EVM account and contract management, allowing you to securely manage your assets.

Blockchain Transactions
Technology

Empowering Secure and Efficient Blockchain Interactions

Do not just trust your Ethereum API provider, verify its honesty by combining the new Klave templates: Light Client and JSON RPC API.

MuSig2
Technology

Enhancing MuSig2 protocol with Klave

Learn how to optimise MuSig2 multi-signature scheme with Klave's confidential computing technology.

Apple
Technology

Apple Intelligence

Apple believes Private Cloud Compute is "nothing short of the world-leading security architecture for cloud AI compute at scale".