Security & trust model
Volta Notes' value proposition is that nobody reads your note except the recipient. This page explains, in specifics, how that's achieved — and the parts where you still have to trust us.
The short version. Your note is encrypted in your browser with a key that never leaves your device. The encrypted blob sits on the Internet Computer. The first read returns the blob and deletes it in a single atomic operation. Anyone — including us — who sees the stored blob without the key sees nothing.
What happens when you send a note
Three steps, all in your browser before anything leaves your machine:
- Generate a 256-bit AES-GCM key using the browser's Web Crypto API.
- Encrypt the plaintext with that key and a fresh random initialisation vector.
- Encode the key into the URL fragment (the part after the
#). Fragments are not transmitted to any server — ever.
The encrypted blob is sent to the Volta Notes canister. The canister stores it under a random 16-character ID and returns that ID. Your final URL is:
https://app.voltanotes.com/r/<note-id>#<key>
The canister sees the blob and the ID. It never sees the key.
What happens when someone reads it
The recipient opens the URL. The browser strips the fragment before sending the request to the canister — the key stays local. The canister looks up the blob by ID, deletes it, and returns it in one atomic operation (Internet Computer update calls are serialised, so two concurrent reads cannot both succeed). The browser then uses the key from the fragment to decrypt the blob locally.
Second read of the same URL returns null. The note is gone.
Architecture on the Internet Computer
Volta Notes runs as two canisters — small WASM programs hosted on a decentralised network of independent node operators:
Backend canister
xswq7-nqaaa-aaaai-q75vq-cai — 231 lines of Motoko. Stores encrypted blobs, rate-limits incoming traffic, burns blobs on first read. View on the IC dashboard.
Frontend canister
xhrbs-myaaa-aaaai-q75wa-cai — static HTML, CSS, and JavaScript, served certified by the subnet so any tampering is detectable in the browser. View on the IC dashboard.
Every response to a Volta Notes query is cryptographically signed by the subnet's threshold key. The HTTP gateway verifies those signatures before forwarding anything to your browser. If a node tries to serve tampered content, the verification fails and the browser gets nothing.
Operational trust — what you still trust us on
The crypto above is deterministic and auditable. The operational side is where honesty matters:
Canister controllers
Both canisters have exactly one controller principal — a key we hold, stored in the macOS Keychain (not on disk as plaintext). That controller can upgrade the canister code.
Controller principal (same for both canisters):
owzzk-iq4kc-luzan-ow5it-qj3vv-ajqyf-stk4v-hci2r-v2zzt-3lki3-iae
This means, today, you are trusting us not to push a malicious upgrade that would, for example, log ciphertext before burning it. The crypto guarantees we can't read your past notes — the key was never on our servers — but a compromised controller could theoretically log future ones.
Planned: we will migrate to a multi-signature controller and, eventually, blackhole the canisters (remove all controllers — the code becomes permanently immutable). We haven't done this yet because the product is new and we still need to ship patches. Once the current code stabilises, the single-controller state is temporary by design.
Published module hashes
The current code running on each canister has a specific SHA-256 hash. You can verify these yourself at any time (see below). As of 2026-04-18:
Backend hash
0xabee8c2a288fe607b6c9d5e8fa3dac8d8a80892ab38a32538d8703eb85c2caf4
Frontend hash
0xf1036e852d2d27418d7b667a9783a38ba84271f5d9730380f1f20b1494d1da82
These hashes will change when we deploy an upgrade. When we do, this page will be updated on the same day. If the hash on the canister ever differs from the one published here, something is wrong — treat it as a trust-compromising event.
How to verify — yourself, any time
If you have the DFINITY SDK installed (docs), you can confirm every claim above independently:
dfx canister --network ic info xswq7-nqaaa-aaaai-q75vq-cai
dfx canister --network ic info xhrbs-myaaa-aaaai-q75wa-cai
The output will show the controller principal and the live module hash. Both should match the values on this page. If they don't, we've shipped an upgrade we haven't documented — send us a note.
Threat model — what's protected, what isn't
Protected Server-side data exposure
A compromised or malicious node operator sees only ciphertext. Without the key — which is never transmitted — the blob is meaningless.
Protected Subpoenas, warrants, data requests
We can't comply with a request for the plaintext of a specific note because we don't have it. We can't build a feature that reads past notes — the key is gone.
Protected Double-reads and race conditions
The Internet Computer serialises update calls. Two simultaneous reads of the same note URL result in exactly one successful read. There is no window where both could succeed.
Protected Link interception in transit
The full URL is served over HTTPS with strict transport security. The key portion (after #) is never transmitted to a server in the first place.
Limitation URL leaks on the recipient's device
If the recipient's browser, clipboard, or screen is compromised, the URL (and therefore the key) can be captured before they read. We set Referrer-Policy: no-referrer to prevent leakage via outbound clicks, but we can't protect against keyloggers, screen recording, or malware on the recipient's machine.
Limitation Intercepted link before first read
If someone intercepts the link (shoulder-surfing, compromised chat app) before the intended recipient opens it, they can read the note once. The recipient's read then returns null — you'll know the link was used, but by then it's too late for the content. Treat any credentials sent via an intercepted link as compromised and rotate them.
Limitation Malicious controller upgrade (today)
As explained above, we currently hold the ability to upgrade canister code. The migration to a multi-sig controller — and eventually blackhole — is on the roadmap.
Limitation Quantum computers
AES-256-GCM is considered post-quantum-safe for the foreseeable future. If a practical quantum computer materialises, symmetric encryption at 256 bits is reduced to ~128 bits of effective security under Grover's algorithm — still comfortably out of reach. This will be revisited if the crypto landscape changes.
Defences on the canister itself
Beyond the crypto, the canister code includes hardening against operational attacks:
- Ingress filtering — malformed requests are rejected before consuming subnet cycles.
- Per-caller rate limits — prevents a single attacker from exhausting the service for everyone.
- Capacity bounds — ceiling on total notes stored, checked after every async yield to prevent races.
- 96-bit random note IDs — guessing a valid ID by brute force is computationally infeasible.
- Tight Content Security Policy — blocks any script from exfiltrating data to a third-party domain, even if one somehow landed on the page.
- Strict security headers — HSTS, COOP, CORP,
Referrer-Policy: no-referrer,X-Frame-Options: DENY. - Raw domain disabled — the frontend is only reachable via certified endpoints, where tampering is cryptographically detectable.
Responsible disclosure
Found a vulnerability? Send the details — ideally as a Volta Note — to security@voltanotes.com. We'll acknowledge within 48 hours and credit reporters in a future hall-of-fame page once the product leaves beta.
Do not publish exploit details before we've had a chance to patch and roll out. Do not test rate limits or capacity bounds against the production canisters — the service is live and other people rely on it. If you need a test environment, email us and we'll spin one up.