Skip to content
· 6 min read

Stop Pasting Secrets in Slack

Tech

There’s a message in your Slack history right now that looks something like this:

@alice here’s the prod DB password: Kx9#mR2$vLp... — sent 14 months ago, #engineering, 3 people copied it to notes

You’ve done it. I’ve done it. Everyone’s done it, because the alternative — setting up a secrets manager, getting everyone on 1Password, configuring Vault, explaining how to use it to your contractor — takes forty minutes and the DB migration is happening right now.

So the secret goes into Slack. And then it lives there. Forever.

It’s worse than you think

The obvious problem: Slack messages don’t expire. That password from 14 months ago is still there, searchable by every current and future team member with channel access. If you ever export your workspace — for compliance, for a legal hold, for an acquisition — that secret is in the archive.

The less obvious problem: Slack has integrations. Your workspace probably pushes messages into a logging service, a compliance tool, maybe a support platform. The secret you sent to one person potentially landed in three different third-party databases you forgot about.

The worst problem: you can’t revoke it. Even if you delete the message, it was already ingested by the logging service. Even if you rotate the credential, you don’t know who copied it. There’s no audit trail. It just quietly exists in the dark.

Email is the same story. More persistent, wider blast radius, worse search discoverability (which means better attacker discoverability). “Can you forward me the creds?” threads forwarded to five more people, all of whom work with their inboxes synced to their phones.

Why the right solutions don’t stick

HashiCorp Vault is excellent. 1Password Teams is excellent. AWS Secrets Manager, GCP Secret Manager, Infisical, Doppler — all excellent. None of them help with the situation described above, because the situation is human, not technical.

You need to give one specific secret to one specific person, right now, through a channel you’re already in. The barrier to doing it safely has to be lower than the barrier to doing it unsafely, or people will always take the shortcut. They’re not lazy — they’re just trying to get work done.

The only fix that works in practice is a tool that’s as fast as paste, works anywhere a link works, and leaves nothing behind.

VoidNote is that tool. You create a note. You get a link. The recipient opens the link, the note is revealed, then it’s gone. The entire flow takes fifteen seconds. The link works in Slack, email, SMS, a GitHub comment — anywhere you’d paste a secret today.

The cryptographic model matters here. Your browser generates a 64-character token and splits it in half:

fullToken  = a1b2c3d4...e5f6a7b8...  // 64 chars total
tokenId    = a1b2c3d4...              // first 32 — sent to server as lookup key
secret     =             e5f6a7b8... // last 32 — lives only in the URL

The content is encrypted with AES-256-GCM using a key derived from the secret half only — before it ever leaves your browser. The server receives an encrypted blob and a lookup token. It has no decryption key. It cannot read your note.

The recipient opens the link. The secret half is in the URL fragment. Their browser downloads the encrypted blob, decrypts it locally, shows the content, increments the view counter. When the view limit is hit, the blob is deleted. The key was never on the server. There’s nothing left to breach.

From anywhere to anywhere

The web interface is the easiest path. But VoidNote is also infrastructure you can call from code.

The simplest example: you’re on your phone, you need to get a secret to your laptop without emailing it to yourself.

# On your phone — create the note, get the link
curl -s https://voidnote.net/api/notes \
  -H "Authorization: Bearer $VN_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content":"my-secret","maxViews":1}'

# On your laptop — consume it, pipe wherever
curl -s https://voidnote.net/api/note/<token> | jq -r .content

Or install the CLI helper: voidnote <link> reads the note, sends content to stdout, metadata to stderr, and it’s gone. One view, one read, nothing left.

voidnote https://voidnote.net/note/abc123... | pbcopy
voidnote https://voidnote.net/note/abc123... > ~/.ssh/id_rsa
voidnote https://voidnote.net/note/abc123... | docker login --password-stdin

CI/CD pipelines and AI agents

The same problem shows up in automated systems. You need to pass a credential to a CI job, a deployment script, or an AI agent — but you don’t want it sitting in an environment variable that outlives the task, or in a config file that ends up in a log.

# In your CI pipeline
- name: Deploy
  run: |
    # Secret injected once, consumed, gone
    DEPLOY_KEY=$(voidnote ${{ secrets.DEPLOY_NOTE_URL }})
    ./deploy.sh --key "$DEPLOY_KEY"

For AI agents, this pattern becomes more powerful. You can give an agent a VoidNote URL instead of a raw credential. The agent consumes it exactly once to do its job — and now you have a cryptographic audit trail: the note was viewed once, at a specific time, from a specific IP. If the note was already consumed when the agent tries to read it, something went wrong in the pipeline.

The SDK makes this three lines in any language:

import voidnote

result = voidnote.read("https://voidnote.net/note/abc123...")
deploy(api_key=result.content)  # result.destroyed is True after this
import * as voidnote from "voidnote";

const result = await voidnote.read("https://voidnote.net/note/abc123...");
await deploy({ apiKey: result.content }); // result.destroyed === true

The mental model that matters

The useful shift isn’t “use a secrets manager.” It’s learning to think of secrets as things that should have a natural lifespan.

A credential you send to a contractor for a one-time task shouldn’t exist six months later. An onboarding password shouldn’t be recoverable after the new hire’s first login. A deployment key passed through a CI job shouldn’t survive the job.

Right now, secrets default to permanent unless you actively delete them from every place they landed. Slack messages, email threads, copy-paste buffers, browser history, terminal history — they accumulate silently. The rot is invisible until it isn’t.

VoidNote flips the default. Secrets are ephemeral unless you explicitly make them persistent. The link expires. The note is destroyed. Nothing accumulates. There’s nothing to breach because there’s nothing left.


Register at voidnote.net/register — 5 free notes on signup, no credit card, optional email. Install the SDKs with npm install voidnote or pip install voidnote. The technical architecture is documented if you want to verify the zero-knowledge claims before trusting it with anything real.

The next time you’re about to paste a credential into Slack — try the link instead. Fifteen seconds. No persistence. Nothing to clean up later.