NoteKillnotes that do not survive

How to share an API key securely

Keys authenticate on their own, from anywhere, with no second factor. That changes how you hand them over.

An API key is a bearer credential: whoever holds the string is the account. That makes handing one to a teammate a different problem from handing over a password, and it is why keys keep turning up in places nobody meant to put them.

Why keys leak more often than passwords

A password is usually paired with a username and often with a second factor. A key is not. It authenticates on its own, from anywhere, with no prompt and no second step. Anything that can read the string can use it.

Keys also travel more. They get pasted into a terminal, a CI configuration, a Dockerfile, a Slack thread, a Jira ticket, a Notion page, a screenshot in a bug report. Each of those is a copy that outlives the reason it was made. The industry's recurring headline — thousands of live credentials found in public repositories — is not the story of people being careless once. It is the story of a string that was copied fifteen times and revoked zero.

If a key has been in a chat message, a ticket or a commit, rotate it. Do that first. Moving to a better handover method does not retract a key that has already been in a searchable archive — and you cannot tell from the outside whether anyone copied it.

Handing over a key, once

  1. Paste the key into a note here. Your browser encrypts it with AES-256-GCM before anything is sent. The 256-bit key is generated on your device and lives after the # in the resulting link, which browsers never transmit in a request.
  2. Set the expiry to the shortest window that works. If the recipient is online, ten minutes. A key sitting in a valid link overnight is a key sitting in an inbox overnight.
  3. Leave the view count at one. The link dies the moment it is opened.
  4. Send the link over your normal channel and say it opens once. The channel does not need to be trustworthy for storage any more, because the thing left in the history stops working.

The property that matters for a key

A one-time link gives you something a pasted string never does: evidence of use. If the recipient reports a dead link, exactly one of two things happened — they opened it already, or somebody else did. Either way you know, and you can rotate. A key pasted into a channel gives you no signal at all; you find out from the billing page.

Server-side, the read-and-delete happens inside a single locked transaction, so two people clicking the same link at the same moment cannot both be served. Exactly one succeeds. That matters more than it sounds: a "one-time" link that can be raced is not one-time.

Where the key is not, and why that is the point

We hold ciphertext. The decryption key existed in your browser and in the link, and nowhere else — not in the database, not in a backup, not in a log. If somebody serves us a legal order for the contents of a note, they get bytes nobody can open, because the material needed to open them was never in our possession.

That is a claim you should not take on faith, which is why /verify exists: it runs in your browser, hashes the code this site served you, and compares it against the hashes published at /integrity.json. The reasoning, including the one limit we cannot engineer away, is set out on /security.

For teams, some habits worth having

Scope before you share. A read-only key for a single project is a smaller problem than an org-wide key, both when you send it and when it leaks.

One key per person or per service. Shared keys cannot be revoked without breaking everyone, so in practice they never get revoked.

Do not put the key and the endpoint in the same message. Two halves in two places is meaningfully better than both in one.

Never paste a key into a group channel. With a one-time link, whoever reads first consumes it and the intended person gets a dead link with no way to tell who took it.

Set a calendar reminder to rotate. The best handover in the world does not help a key that stays valid for four years.

Prefer short-lived tokens where the platform offers them. A credential that expires on its own is better than any sharing method, including this one.

Config files, certificates and .env

When the thing to hand over is a file rather than a string — a service-account JSON, a private key, a populated .env — use /files. It works the same way, up to 25 MB, and the filename and file type are encrypted alongside the contents. We cannot see that you sent something called prod-credentials.json, because that name is inside the ciphertext too.

Hand one over

Write the note on the home page. No account, no signup, nothing to pay — an account would mean a record tying a person to the secrets they sent, which is exactly what should not exist.

Related: sending a password to a colleague or client, why the key goes after the # in the link, and the common questions.