Security Model
Last updated: 2026-04-04 · Alpha version
The one-line claim
RESQD servers cannot read the contents of your vault, cannot read the filenames of the things you store, and cannot access your vault without leaving a cryptographic fingerprint on a public blockchain.
Everything below is what makes that claim honest — and specifically which threats it does and does not address.
Trust boundaries
The browser running this app is the trust boundary. Every key operation happens inside it, before any data crosses the network.
- Inside the browser: plaintext of your files, the master key derived from your passkey, per-asset encryption keys, filenames, and metadata.
- Leaves the browser: encrypted shards (6 per file, 4-of-6 recoverable), a per-asset key wrapped under your master key, an encrypted metadata blob, and your opaque asset IDs.
- RESQD servers (AWS Lambda, S3, DynamoDB) see: ciphertext, wrapped keys, encrypted metadata, your email address (only for account recovery), your passkey public key, and the number and timing of your API calls.
- Base L2 blockchain sees: BLAKE3 hashes of your asset IDs and 32-byte canary commitments. No filenames, no content, no user identifiers.
Cryptographic primitives
- Content encryption: XChaCha20-Poly1305 AEAD, 256-bit keys, 192-bit random nonces.
- Hashing: BLAKE3 (commitments, asset ID derivation).
- Key encapsulation: ML-KEM-768 (NIST-standardized post-quantum KEM) for future key-agreement operations.
- Key derivation from passkey: WebAuthn PRF extension — your authenticator computes a per-credential secret from a fixed salt. The output becomes your master key. The master key never leaves the browser.
- Key derivation from passphrase (fallback, not currently exposed): Argon2id with memory ≥ 64 MiB.
- Erasure coding: Reed-Solomon 4+2. Any 4 of 6 shards reconstruct the original.
- Session tokens: HS256 JWT in HttpOnly cookies; server-held secret never exposed.
- Blockchain anchor: Base L2 (Ethereum EVM L2). Gas per anchor: ~38k. Cost: ~$0.0027.
Zero-knowledge architecture in detail
When you upload a file, these steps happen in order, all inside your browser:
- A 32-byte per-asset key is generated with cryptographically secure randomness.
- Your filename and MIME type are wrapped in a header and prepended to the raw file bytes as a frame.
- The framed bytes are encrypted under the per-asset key with XChaCha20-Poly1305.
- The per-asset key is separately encrypted under your master key.
- Your filename + MIME (only) is also separately encrypted under your master key, for display in the vault list without having to decrypt the whole file.
- The ciphertext is Reed-Solomon coded into 6 shards.
- Six presigned upload URLs are requested from the RESQD API.
- Each shard is PUT directly to its storage backend, bypassing the API.
- The API is told to commit the upload, receiving the wrapped per-asset key and the encrypted filename blob as opaque base64 strings.
- The API creates an initial canary commitment and anchors it on Base L2.
Nowhere in this flow does the RESQD API see a plaintext key, a plaintext filename, or plaintext content. You can verify this yourself by reading the source at github.com/khiebel/resqd (to be published) or by inspecting the browser network tab during an upload.
Canary tamper detection
Every read from your vault rotates a cryptographic canary chain and writes the new commitment to Base L2.
- If RESQD reads your vault without your knowledge, the on-chain sequence number advances past what you expect.
- You can query the contract directly (no RESQD server involvement) to verify the access count.
- Because Base L2 is append-only, RESQD cannot rewrite history to hide an access.
- The canary chain is signed with a per-asset chain, so a malicious administrator cannot replay or forge canaries.
This is the core tamper-evidence guarantee. It converts "trust us that we don't look at your data" into a cryptographically verifiable claim.
What this does NOT protect against
Honest about the limits:
- Malicious browser extensions: Any extension with access to the RESQD tab can read your plaintext before encryption. Use a clean profile for sensitive uploads.
- Compromised endpoint: If your Mac or phone is compromised, the attacker has the same view as you. RESQD protects data at rest and in transit to the cloud — not against a keylogger on your own device.
- Lost passkey with no backup: If your only passkey is lost and the credential is not synced to iCloud Keychain / Google Password Manager, you cannot recover your vault. We can see your encrypted data but we cannot decrypt it. This is by design.
- Quantum-capable adversary with stored ciphertext from 2026: XChaCha20-Poly1305 is believed quantum- resistant against key-search attacks (Grover's algorithm halves effective key length to ~128 bits, which is still secure). The only currently-used primitive at risk from sufficiently large quantum computers is the WebAuthn credential's elliptic-curve signature, and passkey providers are already migrating to PQ signature schemes. We will migrate as well when support lands.
- Traffic analysis: RESQD servers see the number, timing, and size of your requests. A well-resourced observer could learn rough usage patterns even without reading contents. If this matters to you, route traffic through Tor or a VPN.
- Legal compulsion: We will comply with lawful court orders targeting data we hold. Since we hold only ciphertext and wrapped keys, that compliance is bounded: we can hand over the encrypted blobs, but we cannot hand over your plaintext because we do not have it.
Open source and verifiability
The Rust crypto core that runs in your browser as WebAssembly is licensed AGPL-3.0 and will be published publicly. You can compile the WASM yourself from source, diff it against what this site serves, and run the integration tests. The exact binary you trust is the binary you can audit.
The Solidity contract that anchors canary commitments is deployed at 0xd45453477aa729C157E4840e81F81D4437Ec99f3 on Base Sepolia (currently) and is verifiable on Basescan.
Questions, bug reports, or responsible disclosure: security@resqd.ai