How it works & security
The short version: SecureNote is built so that even we can't read your secrets, and a one-time link means anything that does leak has a short shelf life. This page explains the model in plain language first, then the specifics.
The basic idea
- You type a secret, and optionally attach files.
- Your browser encrypts it and sends us only the scrambled version.
- You get a link to share. The key that unlocks the note is tucked into the link itself, in the part after the
#, which browsers never send to a server. - The first person to open the link and reveal the note sees the secret. At that moment it's deleted.
- If nobody opens it, it expires on its own after the time you picked.
So the secret really only exists in two places: the browser that made it and the browser that opens it. Our server just holds an unreadable blob in between. The same model powers secret requests, with one twist explained below.
Why it's safe to use
- Secrets are encrypted in your browser, not on our servers. We only ever receive and store the encrypted blob.
- The key to decrypt lives in the link, after the
#. Browsers keep that part local and don't send it to the server, so it never lands in our logs or database. - A secret can only be read once. The moment it's revealed, the server deletes it in the same step it hands it over — there's no window for a second person to grab it.
- Unopened secrets are purged automatically once their time limit passes.
- Creating a link requires an InternalCars sign-in. That's an abuse control — it keeps strangers from using our domain to relay content — not surveillance: we don't attach your identity to a note or request, so there is no record of who sent what to whom. Opening a link never requires an account.
For the security-minded
If you want the specifics:
- Encryption is AES-256-GCM via the browser's built-in Web Crypto. A fresh random key and nonce are generated for every note.
- That key is base64url-encoded into the URL fragment (
#…). Fragments aren't sent in HTTP requests, so the server only ever sees the note id in the path, never the key. - The server stores the ciphertext plus the bare minimum: an unguessable random id (≥128-bit), an expiry, and (for notes) a hash of the manage token. Not the plaintext, the key, the passphrase, who created it, or even attached filenames — those are encrypted inside the blob.
- Reveal is a single atomic
DELETE … RETURNING, so the row is removed in the same operation that returns it. Two people racing the same link can't both win. Retrieving a request reply works identically, and submitting to a request is a one-shot atomic update, so only the first submission ever counts. - A passphrase is folded into the link's key with PBKDF2 (SHA-256, 600k iterations) to derive the real key. So the link alone won't decrypt a protected note, and guessing the passphrase is useless without the link.
- Secret requests add public-key crypto: your browser generates an ephemeral ECDH P-256 key pair, puts the public key in the customer's link and the private key in your inbox link. The customer's browser derives the AES key from the key agreement (via HKDF-SHA256), so the request link can encrypt to you but never decrypt — and the server still never sees a key of any kind.
- Creation is authenticated with OIDC (Entra ID) — the browser posts through a server-side proxy that attaches the token, so tokens never reach page JavaScript — and the anonymous write endpoint (request submission) is rate-limited.
- Pages ship a strict Content-Security-Policy (per-request script nonces, no inline scripts) and a no-referrer policy, so a link can't leak through a
Refererheader either, and secret-bearing responses are markedno-store.
What it doesn't protect against
Worth being straight about the edges:
- If a full link leaks before the note is opened, whoever finds it can read it (once). Short expiries and a passphrase sent separately are your defenses there.
- It trusts your device and browser. If your machine is compromised, so is anything you type into it.
- Someone holding a request link can trigger the one-time retrieve and destroy a customer's reply before you read it. They can't read it — they never have the private key — but it's gone. If your inbox says nothing arrived when the customer says they sent it, treat that request as burned and issue a new one.
- A convincing look-alike address defeats everything on this page. Before typing a secret, check that the address in your browser is the one your contact actually gave you.
- It's for handing a secret to a specific person, not for storage. Once it's read or expired it's gone. That's the point, not a bug.
Practical guides: send, receive, ask for a secret, or send us one.