Enter model name: glm-5-2
Configuration saved to ~/.hermes/config.yaml
```
Confirm everything is wired up:
```bash theme={"dark"}
$ hermes doctor
✓ Config file exists
✓ Dependencies installed
✓ API connection successful
✓ Model glm-5-2 is accessible
```
### Privacy
Hermes is MIT-licensed and runs entirely on your machine. The Hermes [FAQ](https://hermes-agent.nousresearch.com/docs/reference/faq#is-my-data-sent-anywhere) states:
> API calls go only to the LLM provider you configure (e.g., OpenRouter, your local Ollama instance). Hermes Agent does not collect telemetry, usage data, or analytics. Your conversations, memory, and skills are stored locally in `~/.hermes/`.
With the custom endpoint pointed at the Tinfoil proxy, requests go from Hermes to the local proxy and into the enclave.
# Using Tinfoil with LangChain
Source: https://docs.tinfoil.sh/tutorials/langchain
Use LangChain with Tinfoil.
## LangChain integration
Tinfoil's SDKs expose verified, attested HTTP clients that can be injected into LangChain.
This lets you build chains, agents, and RAG pipelines while using Tinfoil as the backend.
The integration works by passing Tinfoil's secure transport layer into LangChain's OpenAI provider.
All LangChain features work as before.
**Supported languages:** Python, JavaScript/TypeScript, and Go.
### Installation
```bash Python theme={"dark"}
pip install tinfoil langchain-openai
```
```bash JavaScript theme={"dark"}
npm install tinfoil @langchain/openai
```
```bash Go theme={"dark"}
go get github.com/tinfoilsh/tinfoil-go
go get github.com/tmc/langchaingo
```
### Quick start
Create a Tinfoil-verified LangChain client in a few lines:
```python Python theme={"dark"}
import os
from tinfoil import SecureClient
from langchain_openai import ChatOpenAI
# Create a SecureClient for Tinfoil's inference router
sc = SecureClient(
enclave="inference.tinfoil.sh",
repo="tinfoilsh/confidential-model-router",
)
# Inject the TLS-pinned httpx clients into LangChain
llm = ChatOpenAI(
model="",
api_key=os.getenv("TINFOIL_API_KEY"),
base_url="https://inference.tinfoil.sh/v1/",
http_client=sc.make_secure_http_client(),
http_async_client=sc.make_secure_async_http_client(),
)
response = llm.invoke("What is confidential computing?")
print(response.content)
```
```typescript JavaScript theme={"dark"}
import { ChatOpenAI } from "@langchain/openai";
import { SecureClient } from "tinfoil";
// Create and verify the secure client
const secureClient = new SecureClient();
await secureClient.ready();
// Inject the verified fetch into LangChain
const llm = new ChatOpenAI({
model: "",
apiKey: process.env.TINFOIL_API_KEY,
configuration: {
baseURL: secureClient.getBaseURL(),
fetch: secureClient.fetch,
},
});
const response = await llm.invoke("What is confidential computing?");
console.log(response.content);
```
```go Go theme={"dark"}
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/openai/openai-go/v3/option"
"github.com/tmc/langchaingo/llms"
langchainOpenAI "github.com/tmc/langchaingo/llms/openai"
"github.com/tinfoilsh/tinfoil-go"
)
func main() {
// Create a Tinfoil client (verifies the enclave on creation)
tfClient, err := tinfoil.NewClient(
option.WithAPIKey(os.Getenv("TINFOIL_API_KEY")),
)
if err != nil {
log.Fatal(err)
}
// Inject the TLS-pinned HTTP client into langchaingo
llm, err := langchainOpenAI.New(
langchainOpenAI.WithToken(os.Getenv("TINFOIL_API_KEY")),
langchainOpenAI.WithModel(""),
langchainOpenAI.WithBaseURL(fmt.Sprintf("https://%s/v1", tfClient.Enclave())),
langchainOpenAI.WithHTTPClient(tfClient.HTTPClient()),
)
if err != nil {
log.Fatal(err)
}
response, err := llms.GenerateFromSinglePrompt(context.Background(), llm, "What is confidential computing?")
if err != nil {
log.Fatal(err)
}
fmt.Println(response)
}
```
### Streaming
```python Python theme={"dark"}
import os
from tinfoil import SecureClient
from langchain_openai import ChatOpenAI
sc = SecureClient(
enclave="inference.tinfoil.sh",
repo="tinfoilsh/confidential-model-router",
)
llm = ChatOpenAI(
model="",
api_key=os.getenv("TINFOIL_API_KEY"),
base_url="https://inference.tinfoil.sh/v1/",
http_client=sc.make_secure_http_client(),
http_async_client=sc.make_secure_async_http_client(),
streaming=True,
)
for chunk in llm.stream("Explain hardware attestation step by step."):
print(chunk.content, end="", flush=True)
```
```typescript JavaScript theme={"dark"}
import { ChatOpenAI } from "@langchain/openai";
import { SecureClient } from "tinfoil";
const secureClient = new SecureClient();
await secureClient.ready();
const llm = new ChatOpenAI({
model: "",
apiKey: process.env.TINFOIL_API_KEY,
streaming: true,
configuration: {
baseURL: secureClient.getBaseURL(),
fetch: secureClient.fetch,
},
});
const stream = await llm.stream("Explain hardware attestation step by step.");
for await (const chunk of stream) {
process.stdout.write(chunk.content as string);
}
```
```go Go theme={"dark"}
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/openai/openai-go/v3/option"
"github.com/tmc/langchaingo/llms"
langchainOpenAI "github.com/tmc/langchaingo/llms/openai"
"github.com/tinfoilsh/tinfoil-go"
)
func main() {
tfClient, err := tinfoil.NewClient(
option.WithAPIKey(os.Getenv("TINFOIL_API_KEY")),
)
if err != nil {
log.Fatal(err)
}
llm, err := langchainOpenAI.New(
langchainOpenAI.WithToken(os.Getenv("TINFOIL_API_KEY")),
langchainOpenAI.WithModel(""),
langchainOpenAI.WithBaseURL(fmt.Sprintf("https://%s/v1", tfClient.Enclave())),
langchainOpenAI.WithHTTPClient(tfClient.HTTPClient()),
)
if err != nil {
log.Fatal(err)
}
_, err = llms.GenerateFromSinglePrompt(
context.Background(),
llm,
"Explain hardware attestation step by step.",
llms.WithStreamingFunc(func(ctx context.Context, chunk []byte) error {
fmt.Print(string(chunk))
return nil
}),
)
if err != nil {
log.Fatal(err)
}
}
```
### How it works
Each Tinfoil SDK verifies the remote enclave's hardware attestation and pins TLS certificates before any data is sent.
The integration injects this verified transport into LangChain's OpenAI provider:
| Language | Tinfoil transport | Injected via |
| ---------- | -------------------------------------- | ------------------------------------------ |
| Python | `httpx.Client` with pinned SSL context | `ChatOpenAI(http_client=...)` |
| JavaScript | Fetch function with EHBP encryption | `ChatOpenAI({ configuration: { fetch } })` |
| Go | `*http.Client` with pinned TLS | `openai.WithHTTPClient(...)` |
Once injected, every HTTP request LangChain makes -- chat completions, embeddings, tool calls -- goes through the
verified connection. No application code changes are needed beyond the initial setup.
Full Python SDK reference and examples.
Full JavaScript SDK reference and examples.
Full Go SDK reference and examples.
Use function calling with LangChain agents and Tinfoil.
# Backend infrastructure
Source: https://docs.tinfoil.sh/verification/attestation-architecture
This page provides a description of the different components that make up our backend infrastructure. It also describes how Tinfoil guarantees code auditability and data confidentiality using these components.
## Prerequisites
This page assumes some familiarity with the different parts of the
Tinfoil system and the goals associated with attestation and
supply chain transparency verification.
We recommend reading the [technical overview](/verification/verification-in-tinfoil)
first to familiarize yourself.
## Backend infrastructure
The backend architecture is illustrated in Figure 1. All security-critical
components are open source and available on GitHub.
Figure 1: Overview of Tinfoil's backend infrastructure and attestation architecture.
For simplicity, we omit backend components that are not part of the security-critical
path, such as billing and user account management.
These are closed-source orchestration-layer components
that do not need to be attested since they do not touch user requests.
### The Secure Enclave Components
The secure enclave consists of the OVMF firmware that boots the confidential VM (CVM) image.
The CVM serves the attestation and terminates the TLS connection from clients.
#### Confidential VM Image
A [confidential VM](https://github.com/tinfoilsh/cvmimage) (CVM) is a virtual machine whose memory is encrypted by the
CPU so that the host operator (including the hypervisor and any privileged
software) cannot read or tamper with its contents. This is the foundation of
[confidential computing](/verification/secure-enclave-primer). Tinfoil's CVM
image is based on Ubuntu with an [AMD SEV-SNP compatible kernel](https://github.com/amdese/linux/tree/snp-host-latest),
which enables the CPU's hardware memory encryption and attestation capabilities.
We [chose to use Ubuntu](https://ubuntu.com/engage/tinfoil-confidential-computing-guide)
because it provides broad driver and package support
needed for GPU workloads. At runtime, the CVM runs a reverse proxy that terminates
TLS and serves the attestation document, the user's workload
(e.g., an inference server), and any supporting services like model weight
verification. All virtual disks are mounted read-only. The firmware,
kernel, and initrd are measured into the attestation report at boot
time, while read-only model weight volumes are verified separately
with dm-verity and checked against the expected values from the
Sigstore bundle during verification.
#### OVMF Firmware
When a confidential VM starts, the very first code that runs is its boot
firmware. This firmware is essentially the "BIOS" of the confidential VM and
initializes the hardware, sets up memory encryption, and hands off to the Linux kernel.
The firmware is the first thing measured by the CPU for the attestation report.
To ensure reproducibility, Tinfoil uses [a pinned version of the OVMF firmware](https://github.com/tinfoilsh/edk2).
Each build is attested to Sigstore and the exact firmware binary running in the
enclave can be verified against the build log.
### Supply Chain Security Architecture
Outside of the secure enclave, we have a release pipeline that provides
supply chain security for all components that become part of the enclave.
This starts with pinned releases of the firmware, CVM image, and model weights.
The sha256 hash of each of these is configured inside a `tinfoil-config.yml`
which is then committed to a public GitHub repo. A GitHub action runs to
create a release consisting of the build and hardware measurements.
These measurements are then committed to a public append-only transparency log.
#### Modelwrap - ensuring model weights are attested
One challenge we need to address in our supply chain security story is the
problem of loading model weights into the secure enclave at runtime. We get
around this by generating a read-only volume with the model weights and
computing a cryptographic commitment to it that is pinned inside the configuration
file. At runtime, the enclave loads the read-only model weights and rejects any
disk that doesn't correspond to the exact attested commitment. We built a utility
we called [modelwrap](https://github.com/tinfoilsh/modelwrap), which is used both
to generate a pinned version of Hugging Face model weights and at runtime to
verify that the pinned model-weight volume mounted in the enclave matches its attested commitment. You can read more about this
in our [technical blog post](https://tinfoil.sh/blog/2026-02-03-proving-model-identity) on the subject.
#### tinfoil-config.yml
The Tinfoil configuration file is a manifest specifying the model commitment (generated via modelwrap),
container images, CVM version, and resource allocation. It is committed to a
deployment repo and its SHA256 hash is embedded in the kernel command line,
creating a cryptographic link between the config and the running enclave.
This config file is used by the measure-image-action GitHub action to generate
hardware measurements that get pinned to the transparency log.
#### measure-image-action
The [measure-image-action](https://github.com/tinfoilsh/measure-image-action) is our
GitHub Actions workflow that converts a
`tinfoil-config.yml` into a deployment config. When a new release is tagged and pushed
to the config repo,
this workflow builds the enclave image and publishes a signed
Sigstore bundle containing the expected measurements,
linking the open source code to the attested binary.
This bundle is signed with a Sigstore keyless certificate issued for the GitHub Actions workflow and committed to the Sigstore transparency log
making it impossible for us to change the code without also changing
the expected attestation measurements.
### Hardware Attestation
Hardware attestation is the process by which the CPU and GPU produce
cryptographic proof of what code is running inside the enclave. This proof
is what clients verify, in tandem to the bundles committed to the transparency log
at build time, before sending any data.
#### Boot sequence and CPU measurement
When a confidential VM starts, the CPU measures each stage of the boot
process — hashing the code and configuration at each step — and records
the results in a hardware-signed attestation report. Here is the sequence
of what happens during boot:
1. **Firmware**: The [OVMF firmware](#ovmf-firmware) initializes the VM.
Because it is the very first code to execute, it is also the first thing
the CPU measures and includes in the attestation report.
2. **Kernel**: The OS kernel and initrd load from the read-only root
filesystem. These are also measured by the CPU.
3. **Configuration verification**: The
[boot process](https://github.com/tinfoilsh/cvmimage/blob/main/tinfoil/cmd/boot/main.go)
checks that the `tinfoil-config.yml` on disk matches the attested hash
embedded in the kernel command line. This ensures the enclave is running
the exact configuration that was committed to during the
[build](#supply-chain-security-architecture).
4. **Model weight verification**: Read-only model weight volumes are mounted
and verified against their
[modelwrap](#modelwrap---ensuring-model-weights-are-attested) commitments
using [dm-verity](https://docs.kernel.org/admin-guide/device-mapper/verity.html).
dm-verity is a Linux kernel subsystem that intercepts every disk read and
validates it against a Merkle tree root hash, ensuring that no block of
data has been tampered with. See our
[blog post on proving model identity](https://tinfoil.sh/blog/2026-02-03-proving-model-identity)
for a deeper explanation.
5. **Service startup**: The reverse proxy and workload containers start
using the configuration from the attested config.
The CVM is designed to be entirely stateless, meaning that all virtual disks are mounted read-only,
and ephemeral data uses a ramdisk created at boot. There is no persistent
state that could be modified between boots.
#### GPU verification
For GPU workloads, the boot process includes an additional step: it queries
each NVIDIA GPU to verify it is running in confidential compute mode using
NVIDIA's [`local-gpu-verifier`](https://github.com/NVIDIA/nvtrust/tree/main/guest_tools/gpu_verifiers/local_gpu_verifier).
This creates a chain of trust from the CPU to the GPU. If the CPU fails to
verify the GPU's attestation, it aborts the boot process and the enclave
does not start. Because the GPU attestation is linked to the CPU attestation
report, clients verifying the CPU attestation are also transitively
verifying the GPU configuration.
### Client-side verification
Before exchanging application data (e.g., chat completions)
with an enclave, the [Tinfoil SDK](/sdk/overview) verifies the enclave's identity
and integrity. The SDK fetches the
[attestation document](/verification/predicate) from the enclave, which
includes signed runtime measurements, and verifies the certificate chain back
to the CPU's hardcoded root
certificate ([AMD](https://github.com/tinfoilsh/tinfoil-go/blob/main/verifier/attestation/genoa_cert_chain.pem)).
It then fetches the Sigstore bundle, verifies its
signatures against Sigstore's [root trust anchor](https://github.com/tinfoilsh/tinfoil-go/blob/main/verifier/sigstore/sigstore.go#L22),
and checks the [measurement predicates](/verification/predicate#supported-formats)
to ensure the source code and runtime enclave measurements match. Finally, it
opens a TLS connection and confirms the server's public key matches the one in
the attestation document, binding TLS to the attested key and guaranteeing that
the connection terminates inside a verified enclave.
#### Attestation Proxies
The client-side verification process requires data from several external sources:
the enclave's attestation document, hardware manufacturer's certificate chain,
and the Sigstore bundle from GitHub. Fetching each of these directly can hit
rate limits, add latency, and complicate client implementations. Tinfoil operates
three caching proxies to address this. Importantly, none of these proxies are
trusted — every piece of data they serve is independently verified by the client
against hardcoded root certificates or Sigstore's trust anchor.
**Attestation Bundle Proxy**
Tinfoil runs a proxy that returns
everything the verifier needs in a single request: the enclave's attestation
report, the cert chain, the Sigstore bundle, and the enclave's TLS certificate.
This avoids multiple round-trips to different services during connection-time
verification. The [JavaScript SDK](/sdk/javascript-sdk), for example, uses this
proxy by default. This makes the actual verification code stateless -- it's just
a utility that takes a Tinfoil attestation bundle and verifies everything.
**GitHub Proxy**
`github-proxy.tinfoil.sh` caches GitHub release data, including the
Sigstore bundles published by the [measure-image-action](https://github.com/tinfoilsh/measure-image-action).
The cached data is verified through Sigstore's transparency log and cannot
be forged without Sigstore's signing keys.
**AMD KDS Proxy**
`kds-proxy.tinfoil.sh` caches AMD Key Distribution Service (KDS) certificates
used to validate the CPU attestation. The root AMD certificate is embedded
in the [verifier code](https://github.com/tinfoilsh/tinfoil-go/blob/main/verifier/attestation/genoa_cert_chain.pem),
so the proxy cannot forge certificates — full chain validation is always
performed by the client.
## Transport Security
Tinfoil uses two complementary mechanisms to ensure data is encrypted
end-to-end to verified enclaves: TLS key binding and the
Encrypted HTTP Body Protocol (EHBP).
### TLS Key Binding
TLS key binding ensures all TLS sessions terminate inside a verified enclave,
never on a non-enclave host. The enclave’s attestation includes an
enclave-generated TLS public key tied to the measured runtime,
and terminates TLS inside the enclave (inside the CVM) with a non-exportable
private key that never leaves enclave memory. The client verifier compares
the server’s TLS key to the attested key — if they differ, verification fails
and no data is sent. This guarantees that only verified enclaves can decrypt
traffic; intermediaries can forward TCP but cannot terminate or read plaintext.
### Encrypted HTTP Body Protocol (EHBP)
In environments where TLS certificate pinning is not available (such as
browsers), or where the connection needs to pass through an intermediate
server for billing, authentication, or rate limiting, Tinfoil uses
[EHBP](/resources/ehbp) to encrypt HTTP request and response bodies
end-to-end. The SDK fetches the enclave’s attested HPKE public key and
encrypts all message bodies directly to that verified key using
[HPKE (RFC 9180)](https://datatracker.ietf.org/doc/html/rfc9180). HTTP
headers remain in the clear for routing, but the payload is only
decryptable by the attested enclave. This provides the same data confidentiality
guarantee as TLS key binding for request and response bodies, for clients that cannot pin certificates.
A common pattern is to run a proxy server on your backend that adds your
API key and handles user authentication, while EHBP ensures the proxy
never sees the plaintext request or response bodies. See the
[proxy server guide](/guides/proxy-server) for a complete walkthrough
with code examples.
## Chaining Enclaves
In some deployments, multiple enclaves work together to serve a single
request. Each enclave in the chain verifies the next one before forwarding
data, extending the same attestation guarantees across the entire pipeline.
For example, in our inference API backend, verification is chained across
two enclaves. The client SDK verifies the
[confidential model router](https://github.com/tinfoilsh/confidential-model-router),
which runs in its own enclave. The router then verifies the target model
enclave before forwarding the request. Data is encrypted end-to-end at
each hop using attested keys, so neither the host nor the router can read
plaintext outside of a verified enclave.
# Attestation document specifications
Source: https://docs.tinfoil.sh/verification/predicate
Tinfoil Enclaves serve the remote attestation document over HTTP at the well
known endpoint `/.well-known/tinfoil-attestation`.
The document is a JSON object containing a format identifier and a signed enclave
remote attestation payload.
## Schema
```json theme={"dark"}
{
"format": "",
"body": ""
}
```
## Fields
The attestation document is represented as a JSON object with the following fields:
`format` *string ([TypeURI](https://github.com/in-toto/attestation/blob/main/spec/v1/field_types.md#typeuri)), required*
> URI identifying the type of attestation format. This URI is identical
> to the predicate TypeURI field in the enclave's Sigstore attestations, conformant to [in-toto.io/Statement/v1](https://github.com/in-toto/attestation/blob/main/spec/v1/statement.md).
`body` *string, required*
> Base64 encoding of the gzip-compressed hardware attestation report.
> The report embeds user data whose structure depends on the format version:
>
> * **v1 formats**: 32-byte TLS public key fingerprint (SHA-256)
> * **v2 formats**: 32-byte TLS public key fingerprint + 32-byte HPKE public key
>
> Both v1 and v2 predicates use the same register format per below.
## Supported Formats
Tinfoil currently supports the following remote attestation formats:
### AMD SEV-SNP Guest Attestation
**Format URI:** `https://tinfoil.sh/predicate/sev-snp-guest/VERSION`
The attestation format is the base64 encoding of the attestation report structure defined by the [AMD SEV-SNP specification](https://www.amd.com/content/dam/amd/en/documents/developer/56860.pdf).
**Registers:**
* Register 0: SEV-SNP launch measurement
### Intel TDX Guest Attestation
**Format URI:** `https://tinfoil.sh/predicate/tdx-guest/VERSION`
The attestation format contains TDX-specific measurements including MRTD (Measurement Register of Trust Domain) and RTMRs (Runtime Measurement Registers).
**Registers:** ([follow TDX standard](https://www.intel.com/content/www/us/en/content-details/853294/intel-trust-domain-extensions-intel-tdx-module-base-architecture-specification.html))
* Register 0: MRTD
* Register 1: RTMR0
* Register 2: RTMR1
* Register 3: RTMR2
* Register 4: RTMR3 (empty)
### SNP-TDX Multi-Platform Attestation
**Format URI:** `https://tinfoil.sh/predicate/snp-tdx-multiplatform/VERSION`
A unified attestation format that supports both AMD SEV-SNP and Intel TDX platforms within a single measurement structure.
This format enables cross-platform verification and measurement comparison between
SEV-SNP and TDX hardware attestations.
**Registers:**
* Register 0: SEV-SNP launch measurement (equivalent to `https://tinfoil.sh/predicate/sev-snp-guest/v1` register 0)
* Register 1: TDX RTMR1
* Register 2: TDX RTMR2
### Hardware Measurements
**Format URI:** `https://tinfoil.sh/predicate/hardware-measurements/VERSION`
A generic hardware measurement format for attestation documents that contain
platform-specific measurement registers and verification data.
# A primer on secure enclaves
Source: https://docs.tinfoil.sh/verification/secure-enclave-primer
Understand the basics of how confidential computing enabled by secure enclaves provides verifiably private computations in the cloud.
## What is Confidential Computing?
Confidential computing is the process of protecting data **in use** by performing computations inside
a secure enclave (also known as a Trusted Execution Environment, or TEE).
This provides a level of security and verifiability that is impossible to achieve
with traditional cloud computing approaches where data is unencrypted and
fully accessible to the hardware operator.
Unlike encryption at rest (for stored data) or encryption in transit
(for data being transferred over the network), confidential computing focuses
on protecting data while it's actively being processed on the host.
This is achieved by using isolated regions of memory and CPU+GPU resources which form
a secure "enclave" where even the host (such as the cloud provider)
cannot see the internals of the computation or the data being processed.
Secure enclaves prevent access from all privileged software, including the
operating system and hypervisor, while allowing remote verification of the
environment's security through a remote attestation mechanism with a hardware
root of trust.
Think of it as the third layer of encryption. Data at rest is routinely encrypted on
disk. Data in transit is encrypted with HTTPS. But during computation, data has
historically sat in plaintext in server memory, fully visible to anyone with
access to the machine. Confidential computing closes that gap: it keeps data
encrypted during processing and produces cryptographic proof of exactly what
code is handling it, so you can verify both the software and the privacy of your
data without trusting the operator.
You can see how Tinfoil performs this verification automatically by learning
more about our [verification process](/verification/verification-in-tinfoil).
This hardware-backed security model enables sensitive workloads to run in
untrusted environments while maintaining data privacy and integrity,
even if the host is untrusted or compromised by an attacker.
Terminology: We use "secure enclave" as the default term to describe the isolated
environment where computations are processed. When referring to
hardware standards, attestation artifacts, or vendor technologies, we use the
more formal term Trusted Execution Environment (TEE).
## Core security properties
Secure enclaves are designed to provide four hardware-backed protections that ordinary cloud infrastructure does not provide on its own:
* **Confidentiality**: Data is encrypted in memory by hardware and decrypted only inside the protected processor boundary. The operator, the hypervisor, and any other process on the machine only see ciphertext.
* **Integrity**: Code loaded into an enclave cannot be altered without detection. Even someone with root on the host cannot patch or replace the running workload.
* **Verifiability**: The hardware measures every piece of software before it runs, producing a cryptographic record of exactly what is executing. A client reads that record and confirms it matches the expected code.
* **Attestation**: The enclave wraps the measurement and the enclave's identity into a report signed by the manufacturer's silicon. That report is unforgeable, so an imposter enclave cannot fake its way through verification.
## Who you trust, and who you don't
Confidential computing draws a clear line between what you trust and what you verify:
* **You trust** the hardware manufacturer (AMD, Intel, or NVIDIA) to correctly implement the silicon root of trust and the cryptographic primitives the enclave relies on.
* **You verify** the application code through measurements, signed releases, and transparency logs before sending data to the enclave.
* **You do not trust** the cloud provider's software stack, the hypervisor, the host operating system, system administrators, or other tenants on the same machine. None of them can see inside the enclave.
This is what makes the model work: the hardware itself enforces isolation, so you no longer need to trust the operator of the machine.
## How a secure enclave is built
A secure enclave is built from three pieces of silicon working together inside the processor:
**The memory encryption engine.** Both AMD and Intel embed an AES encryption engine directly in the memory controller, the component that sits between the CPU cores and RAM. Every time data is written to memory, the engine encrypts it on the way out. Every time data is read back, the engine decrypts it on the way in. This happens transparently in hardware, usually with low overhead, though performance depends on the workload and platform. The encryption keys are held in registers inside the memory controller and are never exposed to software, not even to the hypervisor.
**The secure processor.** A dedicated security processor embedded in the CPU manages the encryption keys. It generates them at boot, assigns a unique key to each enclave, and locks them into the memory controller's registers. No other software on the machine can request or intercept those keys. Both [AMD](https://www.amd.com/en/developer/sev.html) and [Intel](https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/overview.html) implement this design.
**The CPU's memory-access checks.** With encryption in place and keys locked away, the final piece is enforcement. The CPU extends its page tables with hardware-enforced metadata that marks every physical page as either secure or regular. On every memory access, the CPU checks this metadata before allowing the read or write to proceed. If the hypervisor tries to map a secure page into a regular VM, the CPU blocks the access in hardware. This is not a policy check. It is a silicon-level gate.
The result is a hardware-isolated region where code and data are encrypted whenever they leave the CPU die. The operating system and hypervisor continue to manage the regular world normally, but neither has any path into the secure region. They cannot read, write, map, or replay those pages. The boundary is enforced by the memory controller and the CPU, not by software.
## Supported hardware
There are several options for instantiating secure enclaves on modern processors.
While traditionally enclaves were restricted to CPU-only workloads,
the latest NVIDIA GPUs now offer the ability to run them by enabling
a special "confidential compute mode."
| Vendor | Platform | Feature | Type |
| ------ | ------------------------------------------------ | --------------------------- | ---- |
| AMD | EPYC 3rd–5th Gen (7003, 8004, 9004, 9005 series) | SEV-SNP | CPU |
| Intel | Xeon Scalable 5th Gen, Xeon 6 | TDX | CPU |
| NVIDIA | H100, H200, B200 | Confidential Computing Mode | GPU |
## Understanding Remote Attestation
Enclave verifiability is a critical security feature that allows users to
confirm that code is running in genuine hardware with hardware
security features enabled.
Tinfoil's integrity features ensure that all code and data remain unchanged
and verifiable through cryptographic remote attestation.
### The attestation process
The attestation process establishes a chain of trust from the hardware
level up to the application level.
Each step builds upon the security guarantees of the previous one to create a
chain of trust connecting the hardware to application code it is running.
1. **Hardware Authentication**
The process begins by verifying the authenticity of the physical
hardware components. This step ensures the enclave is running on genuine
chips with proper security features enabled, not on simulated or
misconfigured CPUs or GPUs.
2. **Configuration Verification**
Once hardware authenticity is confirmed, the system validates that
all security-critical settings are properly configured. This ensures the enclave
environment is set up with the correct parameters and isolation boundaries.
3. **Code Measurement**
The hardware creates cryptographic measurements of all code and configuration
loaded into the enclave at launch. Clients can later verify these measurements
to confirm the enclave is running the expected code.
#### Chain of trust
The attestation chain is established through a series of cryptographic validations:
1. **Hardware Root of Trust**: Hardware manufacturers (Intel, AMD, NVIDIA)
embed cryptographic keys in their processors at manufacture time
2. **Firmware Validation**: Hardware validates firmware integrity during boot
3. **Initialization**: Firmware initializes the enclave with verified security parameters
4. **Measurement**: The hardware measures the loaded code and records cryptographic evidence
5. **Attestation Report**: A hardware-rooted component signs the measurements using keys chained to the manufacturer's certificate authority
6. **Verification**: Clients verify signatures and measurements against known-good values
On AMD SEV-SNP, the CPU's secure processor (PSP) signs with the VCEK, a per-chip key chained to AMD's root key. On Intel TDX, a Quoting Enclave signs with an attestation key chained to Intel's PCK certificate.
## Understanding confidentiality
Secure enclaves provide an isolated execution environment directly at the hardware level.
You can think of it as a "computer within a computer," with its own dedicated memory regions and
processing capabilities that remain completely isolated from the rest of the system and the
hardware operator (e.g., Tinfoil).
When code runs within a secure enclave, it is executed in a protected region where
even privileged system software like the operating system, hypervisor, and
system administrators cannot
access or modify the data being
processed.
In modern secure hardware processors like Intel TDX and AMD SEV-SNP,
all data in memory is automatically encrypted using keys that never leave the processor.
Because memory is always encrypted, data outside the processor is inaccessible
to software-based attackers:
* Memory dumps cannot reveal sensitive information.
* Cold boot attacks are ineffective since memory contents remain encrypted.
* Direct Memory Access (DMA) attacks are blocked.
* Physical memory probing yields only encrypted data.
**Secure key management**:
* Encryption keys are generated within the processor and never leave the processor.
* Keys are automatically destroyed when the enclave terminates.
### Limitations of enclaves in practice
While secure enclaves provide strong guarantees, they are not a silver bullet.
* **Physical attacks**: An attacker with physical access to the hardware can potentially compromise the enclave. For Intel TDX, attestation forgery has been demonstrated; for AMD SEV-SNP, researchers achieved confidentiality breaches through key extraction ([tee.fail](https://tee.fail)). These attacks require significant resources and physical proximity to the machine.
* **Side-channel attacks**: Enclaves can be vulnerable to timing attacks, power analysis, and electromagnetic emissions that leak information about the data being processed.
* **I/O pattern leakage**: The host can observe data access patterns and I/O behavior, which may reveal sensitive metadata even though the data itself remains encrypted.
* **Denial of service**: The cloud provider controls resource allocation and can restrict or terminate access to the enclave at any time.
* **Supply chain attacks**: The hardware, firmware, and software built and shipped into an enclave all depend on a supply chain that could be compromised before deployment, for example through a malicious build pipeline or tampered dependency. Tinfoil hardens its own build and release pipeline against these attacks; see [Supply Chain Security](https://tinfoil.sh/blog/2026-05-01-supply-chain-client).
* **Rollback attacks**: An attacker may try to revert an enclave or its components to an older, vulnerable version. Measured boot detects modified code, but defending against rollback to a previously valid version requires versioned measurements and anti-rollback controls.
# How verification works in Tinfoil
Source: https://docs.tinfoil.sh/verification/verification-in-tinfoil
A technical overview of how Tinfoil guarantees code auditability, supply chain security, and data confidentiality with client-side verification.
## Overview
This page explains the basics of how Tinfoil provides **verifiable** privacy on
each connection. Tinfoil uses [confidential computing
enabled by secure hardware enclaves](/verification/secure-enclave-primer) to create a *verifiably private* runtime
environment in the cloud. The hardware measures and attests the code running in the enclave
and we connect these measurements to open source code using transparency logs
to ensure end-to-end supply chain security.
To make it easier to understand the different components involved, we must first
cover the three main parts that make up the Tinfoil system. We have:
* a trusted client that runs one of the Tinfoil SDKs and makes requests,
* an untrusted host machine operated by Tinfoil, and
* a secure hardware enclave that runs a server in isolation from the host.
Client requests get sent using the Tinfoil SDK to the server running in the enclave.
Before sending any data, the SDK automatically verifies that:
1. The enclave server is running code that is auditable and immutable
2. The enclave server computation is isolated from the host operator
3. The client request data is end-to-end encrypted to the enclave (only the enclave can decrypt it)
### Example: Private Inference
To provide a concrete example, consider our [Private Inference](https://tinfoil.sh/inference) service.
Simplifying slightly, we have an enclave with an AI model loaded inside of it.
This enclave is running an open-source inference server (we use vLLM) that serves the
model and exposes the /v1/chat/completions API endpoint.
A client sends encrypted requests to this endpoint.
The enclave decrypts these requests (only the enclave has the decryption key) and forwards them to the inference
server running inside. The response is then encrypted and sent back to the client.
#### The problem of code transparency and confidentiality
How can the client be convinced that the enclave is running vLLM as the
inference server and not some other (potentially evil) code?
Additionally, how can the client verify the end-to-end encryption is enforced to the enclave and isn't man-in-the-middled by the host?
You can easily imagine a scenario where the host *pretends* to be the enclave and
decrypts the clients request, violating confidentiality.
We answer these questions in two parts.
## Part I: Verifying code transparency with remote attestation
The first thing the client needs to be able to do is verify that the enclave
is configured correctly and running the expected code.
This is achieved with remote attestation.
The hardware manufacturer provides a root of trust which is used to prove
what's running its own hardware using a signing key embedded at manufacture time.
In a nutshell, the CPU comes with a secret key fused into it by the manufacturer (e.g., Intel or AMD).
This key is used to sign the initial configuration and state of
the CPU and memory at boot time. The host cannot access this signing key and
extraction of the key is assumed impossible.
At boot time, the hardware measures the initial state, generating
a signed attestation report of the exact launch configuration, such as the
firmware, kernel,
security parameters, and the application binary running in the enclave.
The attestation report can be seen as a cryptographic fingerprint of this
entire launch configuration. If the same configuration is loaded twice, the fingerprints match.
However, if any component differs (e.g., a firmware change, a modified kernel, or a
different binary) then the fingerprints won't match.
This gets us part of the way towards full code transparency. The missing link
is connecting the fingerprint to human-readable code that can be inspected
for correctness and audited for security.
### Linking fingerprints to code
All the code running inside the enclave is published to our GitHub and made open source.
In theory, you could rebuild the same binary, go through the attestation process
yourself, and then see what fingerprint comes out the other end. If the fingerprint
you derive matches the one obtained through remote attestation, then you can be
convinced that the code running in the enclave was built from the open-source
code published on our GitHub repo.
However, this runs into some complications.
First of all, ensuring reproducible builds is a challenging problem and generally
compilers can have some non-determinism resulting in the same code compiling to different binaries.
Recall that if the binaries do not match, then the fingerprints won't either,
making this verification process fail even though we would have wanted it to pass.
Second, relying on reproducible builds creates hurdles in verifying the full supply chain
efficiently, since you would need to download the code, build it, and measure everything
on the same hardware configuration in order compare the fingerprints.
#### Leveraging transparency logs
Instead of relying on reproducible builds, we designed a simpler approach that
provides the same supply chain transparency guarantees while enabling more efficient verification and auditability.
The idea is to have GitHub build the binary for us using the same host and enclave
configuration that we plan on running in production. The GitHub build process then
publishes the resulting attestation measurements onto an immutable transparency log
(we use Sigstore, a transparency log managed by the [Linux Foundation](https://www.linuxfoundation.org/)).
This transparency log
independently attests that the binary was compiled by GitHub itself and produced the
"ground truth" fingerprint. This makes it so that anyone can easily compare the ground
truth fingerprint to the one received
from the Tinfoil enclave, resulting in full supply chain transparency.
## Part II: Providing end-to-end encryption
The second problem is ensuring that the connection from the client is encrypted directly to the enclave.
How can the client verify that the public key it is encrypting all the requests with
was generated by the enclave and not the host? This requires tying the
public key to the signed attestation report, proving it was generated by the enclave itself.
At boot time, the enclave generates an encryption key pair, consisting of a public
key and a secret key. The secret key is
stored in the enclaves encrypted memory while the public key is made part of the
attestation report.
When the client connects to the enclave, all data sent over that connection is
encrypted using the enclave's attested public key.
We additionally hash the attestation report ad store the hash in the
certificate issued to the enclave. We do this to bind the attestation report
to a `*.tinfoil.sh` domain and prevent any third party enclave from cosplaying
as a Tinfoil controlled enclave.
## How our SDKs automatically verify everything
Our SDKs are all open-source and run all verification logic client side.
We do not use any
proprietary or third party attestation services to verify
attestation reports since doing so results in circular security and defeats
the point of doing any verification in the first place.
On each connection, our SDKs
automatically fetch the expected enclave measurements from
GitHub and Sigstore and then proceed to verify the enclave attestation report.
The whole client-side verification proceeds by first assembling the necessary
bundles, validating the configuration of the enclave, and verifying the
cryptographic signatures.
First, the SDK obtains the Sigstore bundle
associated with the latest enclave code release published on the GitHub repo.
Second, it obtains the attestation report generated by the remote enclave.
In our SDKs, these values are assembled and provided by Tinfoil to minimize the
number of requests made to to GitHub, Sigstore, and the enclave.
Proxying and caching this verification material on Tinfoil servers does
not harm security because each component is signed independently by Sigstore
and the hardware manufacturer.
Once all the verification material is assembled, the SDK compares the expected
Sigstore-provided measurements to the enclave-attestation measurements,
if these don't match, the SDK throws an error and stops all connections
from being established.
On the other hand, if the measurements match, then the client creates an
encrypted connection to the enclave using the public key from the attestation report.
## Chaining enclaves
The process described above is essentially what happens when you connect
to `inference.tinfoil.sh`
using one of our SDKs and do inference requests.
However, in our production deployment, we use multiple enclaves
to serve the same model (this allows us to load balance requests) and additionally,
for convenience, we need a model router server.
Without a model router, we'd need to have all models running on the same machine
associated with `inference.tinfoil.sh` which is not reasonable to do in production.\
The model router is responsible for proxying requests to the right enclave.
The solution is to chain enclaves.
The router runs inside its own enclave. The client-side SDKs verify the router enclave
and ensure the transparency of the router code.
The router server then does the same verification for each enclave it routes to.
Similarly, all data from the router to the
inference server is encrypted with an attested key, ensuring that the whole
pipeline from client to model keeps data encrypted from the point of view of the host.
By chaining the attestations, we get end-to-end code transparency and confidentiality,
even though the client-side SDKs only need to verify the first enclave in this chain.
Figure 1: Simple view of model router and inference attestation.
## In-band vs. out-of-band verification
The verification described above is **connection-time (in-band)** verification — the client verifies the enclave's attestation before exchanging any data. This is what our [SDKs](/sdk/overview) do automatically on every connection.
In the future, Tinfoil plans to supports **audit-time (out-of-band)** verification, where an auditor verifies an enclave after the fact by inspecting material committed to an append-only transparency log.
### Audit-time verification through attestation transparency
Audit-time verification relies on embedding attestation evidence into TLS
certificates, which are then recorded in public [certificate transparency (CT)](https://certificate.transparency.dev/) logs.
This serves two purposes: (1) it creates a public audit trail of every enclave boot,
and (2) it binds the attestation to a `*.tinfoil.sh` domain, preventing a
third-party enclave from impersonating a Tinfoil-controlled enclave.
At boot time, each enclave generates a fresh ECDSA key pair for TLS and an HPKE key pair for application-layer encryption (used by [EHBP](/resources/ehbp)).
It then requests a CPU attestation report that covers both the TLS key fingerprint and the HPKE public key,
cryptographically binding them to the measured enclave state.
The attestation report is hashed and embedded in the Subject Alternative Name (SAN) field of a standard x509 TLS certificate.
To obtain this certificate, the enclave registers an ACME identity and
submits a certificate signing request to a public certificate authority,
including the attestation-bearing SAN extension.
The CA issues the certificate, which is automatically recorded in public CT logs.
The resulting certificate ties together the enclave's TLS and HPKE public keys, its CPU attestation report,
and its `*.tinfoil.sh` domain into a single publicly logged artifact.
Explore the full backend architecture, including the CVM image, Sigstore integration, and the build-to-deployment lifecycle.