NoteKillnotes that do not survive

The one-time secret link, taken apart

Two halves in one URL, and only one of them ever reaches a server.

A one-time secret link is a URL that delivers something once and then stops working. It is the simplest useful primitive in this space, and the details of how it is built decide whether it is genuinely private or merely tidy.

The shape of it

You put a secret in, and you get back a link. You send the link. The first person to open it receives the secret, and the server's copy is deleted in the same operation. The link is now dead for everyone, including you.

What makes this better than sending the secret directly is not that it is harder to intercept — the link is exactly as interceptable as the message would have been. It is that the copy stops existing. The secret does not accumulate in a chat history, an email archive, a compliance backup and a search index, waiting for a future incident to surface it.

Anatomy of the link

A link from this service looks like this:

https://notekill.com/n/a17f…c2a9#HYUe…SYag

Two distinct parts, and the split is the entire design:

Before the # — the identifier. 128 bits of randomness naming which stored blob to fetch. This part is sent to the server. Knowing it lets you ask for the ciphertext; it does not let you read it.

After the # — the key. A 256-bit AES key, generated in your browser by the operating system's cryptographic random source. Browsers do not include the fragment in HTTP requests, so this half never reaches the server. It exists in your browser, in the link, and in the recipient's browser. Nowhere else.

So the server holds one half of what is needed and the link holds the other. A demand for our data yields ciphertext and an identifier. There is no key to hand over, because there is no key here.

What "one time" has to survive to be true

Three failure modes turn a one-time link into a sometimes-link, and all three are invisible until they bite:

  1. Two people opening it at the same instant. If the read and the delete are separate steps, both readers can be served before either deletion lands. Here they happen in one database transaction with the row locked, so exactly one succeeds. We test this by firing eight simultaneous requests at one link and confirming that seven of them get nothing.
  2. Expiry that depends on traffic. If old entries are only cleared when somebody happens to make a request, then a quiet weekend means nothing expires. A sweep runs here every minute from the server's own scheduler, so a link nobody ever opens still disappears on time.
  3. Deletion that is not deletion. Marking a row as inactive, or moving it to a "deleted" table, keeps the secret. Here the row is removed and, for files, the encrypted bytes are unlinked from disk.

Choosing the settings

You control two things when you create a link:

Expiry, from ten minutes to seven days. Pick the shortest window in which the recipient will realistically open it. A link valid for a week is a secret sitting in someone's inbox for a week.

View count, which is one by default. Raise it only when you have a specific reason — sending the same credential to three people who each need it, for instance. Every extra view is another chance for the wrong person to be first.

The dead link is a feature

Because it works exactly once, a link that has already been used tells you something. If your recipient reports it dead and it was not them, somebody else opened it — and you now know to rotate whatever you sent. Compare that with pasting a secret into a channel, where a secret read by the wrong person looks identical to one read by the right person, forever.

That is why a spent link here shows a plain statement that the note was destroyed, rather than an inviting button that will fail. The state of the link is the message.

The key is in the link and nowhere else, so if you lose the link, the secret is gone permanently — for you, for the recipient, and for us. There is no recovery, no reset, no support ticket that can retrieve it. That is not a gap in the service; it is the same property that makes it private. A system that could recover your secret for you is a system that could hand it to somebody else.

Checking rather than trusting

Every claim above is about how the code behaves, which means you should be able to check it. The hashes of every file this site serves are published at /integrity.json, and /verify runs the comparison in your own browser, against what your browser saw on previous visits. The full architecture, including the one limit that no browser-delivered tool can remove, is on /security.

Create one

Start on the home page — no account, no email address, no cookies. For a file, /files works identically up to 25 MB, with the filename and type encrypted alongside the contents.

Related: sending a password, handing over an API key, what burn-after-reading really means, and why the key goes after the #.