threatmodel.md
On this page

Attested relay v2 threat model

Status: deployment update, 2026-09-12 (Pacific). This document describes the intended security properties, deployed design, and known gaps; it is not a claim that all properties have been proved.

Measured production source: 30feebbeea8588fb1d1aa7b5ef40c9903bec0df5. It is running non-debug on 24 reserved Graviton5 cores of a 32-core c9g.8xlarge, with Mullvad up and serving requests after full-work generation. Its 96 serially wrapped groups require exactly 465,000,000 hashes for recovery. Commands support upstream methods and password-tagged pastes over the existing GET transport. Live production acceptance, rollout and build evidence, protocol, requirement audit, and earlier Astra review. Earlier reviews predate the new command and progress code.

1. Security objective

An independently verifying client should be able to send an HTTPS request through the relay without giving the EC2 account owner, parent operating system, or relay front end the request URL, request plaintext, response plaintext, or enclave secrets. The intended upstream necessarily receives its request and knows its response. Protection cannot extend to information that the client or an intended plaintext recipient voluntarily gives to another party. In particular, a destination colluding with the operator can disclose the complete exchange immediately; AWS trust and RandomX strength do not prevent that.

Encrypted audit records are deliberately recoverable later through public RandomX puzzles. Confidentiality is temporary and conditional on the assumed cost of solving those puzzles. This is not permanent encrypted storage.

2. Trust assumptions

AWS itself is trusted; the AWS account owner is not. We rely on Nitro isolation, the NSM's entropy and signed time, AWS's attestation PKI, the hardware presented to the enclave, and the authenticated EC2 API's account of the instance. A malicious AWS provider capable of falsifying those mechanisms is outside the implemented protection.

Other assumptions:

Application code, parsers, cryptographic-library integration, native RandomX, the kernel/bootstrap, dependencies, and the build chain are review targets. Pinning and reproducible measurements do not prove that this software lacks bugs or that a compromised compiler cannot produce malicious code.

3. Assets

4. Adversaries and capabilities

Adversaries may collude. The confidentiality objective covers information that they cannot already obtain as intended plaintext recipients; it cannot prevent recipient disclosure described in section 1. Malicious upstream inputs remain in scope for exploitation of the enclave and disclosure of other users' data.

Actor Capabilities considered
EC2 owner/root and parent host Control parent processes, vsock/network proxies, credential replies and storage acknowledgements; observe traffic; replace, reorder, replay, truncate or withhold bytes; launch other images; kill/restart enclaves; delete host-held artifacts.
Cloudflare/relay front end and network Control outer HTTPS termination, URL handling, caching and routing; inspect outer ciphertext and metadata; replay, alter or suppress transport operations.
Mullvad VPN operator Observe destination IPs, timing, sizes and unencrypted TLS metadata; drop, reorder or alter tunnel traffic. Upstream TLS remains authenticated inside the enclave. The account owner can revoke or replace the registered device key and deny service.
DNS resolver and upstream websites Return hostile DNS/HTTP/TLS inputs and redirects, large or slow bodies, and misleading content; attempt SSRF and parser/resource attacks. Their authentic certificates do not grant trust in their responses.
Anonymous relay clients Choose requests, establish concurrent sessions, disconnect at awkward points, and attempt denial of service or exploitation of enclave code.
Archive hosts and external solvers Corrupt, omit, replay or replace artifacts and progress claims; withhold results; publish wrong keys; coordinate and share computed work; use faster hardware.

A compromised client or its tool provider may already see that client's inputs and outputs. The relay does not protect a user from software that handles their plaintext before encryption or after decryption.

5. Trust boundaries and required invariants

Client to enclave

Outer GET operations carry an inner TLS connection. Before transmitting an upstream request, the client must verify the AWS-rooted COSE document, a fresh nonce and timestamp, the exact nondebug PCR0, required hardware/work policy, readiness, and the binding to the actual TLS peer's SPKI on that connection. Relaying somebody else's valid attestation must not authenticate an attacker's TLS endpoint. Historical evidence must not substitute for a fresh live check.

An upgrade requires explicit acceptance of a new measurement. There is no automatic acceptance of whichever PCR the operator advertises as latest. A literal fetch-only tool cannot independently execute this TLS/COSE protocol; there is no verified plaintext fallback.

Enclave to host, AWS and upstreams

Host-provided identities and credentials are untrusted inputs. Hardware acceptance combines local CPU identity, fresh NSM PCR4 parent binding, and an enclave-authenticated EC2 API response for the matching instance.

Upstream TLS verification happens inside the enclave. Resolved destinations and redirects must remain within the public HTTPS/port-443 policy. Parent responses, DNS/HTTP bodies, connection counts and operation lifetimes require bounds before untrusted input can cause unbounded resource use.

Production upstream connections and their DNS-over-HTTPS lookups require an in-enclave Mullvad WireGuard tunnel. Its private key comes from NSM and is never accepted from or exported to the parent. One measured device ID is reused; each boot rotates its public key, and retries never create or delete devices. A missing, dead or stale tunnel blocks upstream traffic, including an accidental Direct mode. Public bootstrap lookups, Mullvad registration and AWS hardware verification may connect directly. Signed policy includes tunnel readiness and the egress mode.

Entropy, epochs and disclosure

Production must successfully obtain NSM randomness and reseed the kernel before TLS initialization. Signing keys, epoch keys and private puzzle material use direct, fallible NSM randomness; failures must not silently select a weaker path.

Future puzzles remain private. A key cannot serve traffic before its puzzle's publication acknowledgement. Delayed acknowledgements cannot extend the lifetime of an already disclosed puzzle. Expired epochs reject new work even when their successor is late. Admitted requests retain bounded completion leases.

App-owned key buffers are zeroized on release where implemented. This is not proof of erasing every compiler, allocator, library, kernel or hardware copy. An independent native probe confirmed that register bytes retained after the VM destructor can reconstruct a final segment output with one BLAKE2b operation. No externally reachable memory-read primitive was found; obtaining the final segment's residual state would nevertheless allow early epoch-key unwrapping. See the native review. Attestation also does not establish general resistance to microarchitectural side channels. Concrete attacks available to an in-scope adversary must be investigated, not dismissed merely because the code is measured.

Response capture and storage

Before returning the upstream response, the enclave encrypts the audit record and waits for the parent's persistence acknowledgement. This establishes the ordering in the enclave; a malicious parent's acknowledgement is not proof of durable storage or replication.

A host can also kill the enclave after an upstream has observed a request but before capture finishes. Consequently, this is not an unconditional guarantee that every upstream interaction survives in the archive. Both method commands and legacy GET requests can cause destination-side effects.

Archived evidence and recovered records

Puzzle signatures are bound to the Nitro-attested service key. Archive checks must bind the puzzle, signer, attestation, content-addressed files and required PCR/hardware policy, while distinguishing historical identity from liveness. Wrong recovered keys and modified ciphertext must fail their commitment/AEAD checks.

Individual record envelopes are not service-signed. Once the epoch key is public, anyone holding it can create another valid AEAD record. Proving an original historical relay interaction therefore also requires a previously trusted ciphertext digest/receipt or independent publication record. A fresh digest supplied by a malicious archive does not solve this problem. Neither AEAD nor a signed puzzle proves archive completeness.

6. Deliberate leakage and limits

7. Known gaps and deployment status

8. Instructions for subsequent security reviews

Use this model to identify violations, not to explain away bugs. Report the attacker capability, reachable entry point, violated property, concrete trigger, and evidence or reproducer. Distinguish current defects, unverified assumptions, accepted disclosure, and proposed stronger guarantees. Review the actual pinned source and relevant deployment state; do not infer runtime security from a PCR, a green test suite, or another model's conclusion alone.

Disagreements with these assumptions—especially trust in AWS, approximate delay, record provenance, and storage durability—must be raised explicitly before claiming that the implementation satisfies a stronger threat model.

Tagged pastes

Tags act as shared read/write passwords. Anyone guessing a tag can use the same public API as other agents. Scrypt slows online/offline guessing; low-entropy tag names do not satisfy unconditional name or content secrecy. Long random tags provide the intended password security. Opaque tag IDs are intentionally public, exposing grouping, counts and access patterns. The host can omit, reorder or withhold results; no completeness claim is made. All paste plaintext and tag passwords travel inside attested inner TLS.

Per-paste content keys are derived with a separate HKDF domain from the same existing epoch keys; tag holders receive only individually wrapped paste keys, not epoch keys or relay-traffic keys. Tag wrappers allow access after old epoch keys are erased. Public epoch recovery unlocks only that epoch's paste contents; it does not reveal tag passwords or automatically unlock later epochs. Authors may disclose passwords in their own content. Signatures and AEAD bind paste metadata, tag ID, puzzle identity and signer; public recovery authenticates the signer through the corresponding independently attested manifest.

The 100 KiB paste limit, 256-byte tag limit, two KDF workers, ten-entry page limit, shared request admission and a 30-second operation deadline bound resources. The existing assumptions about computational delay, storage acknowledgements, replicas, metadata leakage and imperfect memory erasure still apply. Detailed protocol and API design.

The short-work Nitro paste test, public Cloudflare 100 KiB round trip and independent epoch-key recovery passed. Full-work production paste write/read and tag isolation also passed; completed full-work recovery and rollover remain unverified. Paste rollout evidence.

Public generation telemetry

GET /v1/key-production exposes only aggregate generation counters: phase, generation number, completed/total hashes and groups, worker count, elapsed time, service readiness and Mullvad status. It includes no seeds, intermediate chain values, epoch keys, tags or application request data. The host can forge or withhold this telemetry; it must never authorize a client request or replace fresh Nitro/TLS verification. The dashboard labels this distinction explicitly.

The command API has bounded bodies and headers and forbids routing/framing header overrides. It performs no application retry or redirect following for send_request; a missing reply does not prove that a destination operation had no effect. The legacy GET route retains its bounded redirect behavior.