The problem with how most teams share API keys
A contractor starts Monday. By Tuesday they need a Stripe secret key, an AWS access key, or a third-party API token to do anything useful. The path of least resistance is a Slack DM, a shared Google Doc, or — still surprisingly common — an email. The key lands in its destination, the contractor does the work, and everyone moves on.
What nobody cleans up: that key now lives in Slack's message history, Google's servers, and possibly a sent-items folder, indefinitely. When the contractor wraps up in six weeks, you remember to rotate the key (maybe), but you probably don't remember to scrub the DM thread where you sent it. Now you have a rotated key and a revoked contractor, but the old credentials are still sitting in a chat log that three other people on your team can read.
This is the threat model most teams don't think about until something goes wrong.
Why chat and docs are the wrong channel for credentials
Slack retains messages by default. Google Docs log every viewer. Email servers hold copies at every hop. None of these channels were designed to carry secrets, and all of them treat your API key the same way they treat a lunch order: store it, index it, make it searchable.
The specific risk isn't just theft by an outsider — it's ambient exposure. A key in a Slack channel means anyone with access to that channel, now or later (including new hires who join after the fact), can scroll back and find it. A key in a Google Doc means Google Workspace admins can audit it. These aren't paranoid scenarios; they're the default behavior of the tools you're already using.
If you've thought carefully about why email is a bad transport for sensitive data, the same reasoning applies here — the persistence problem is the same, just wearing a different interface. The case against email for sensitive information comes down to retention and visibility, and chat apps share both flaws.
A one-time link solves the persistence problem
The core issue is that normal sharing channels keep a copy. A one-time link doesn't. You compose the note containing the API key, the link is generated, and the moment the contractor opens it, the note is gone from the server. There's no retrievable copy, no search index, no audit log that reveals the secret itself.
With SecureNotes, the encryption key lives in the URL fragment — the part after the #. Fragments are never sent to the server as part of an HTTP request, which means the server processes the request without ever seeing the key used to decrypt the note. The contractor's browser decrypts the content locally. Once they've read it, the note is deleted. You can read more about how that mechanism works in the post on zero-knowledge architecture in SecureNotes.
The practical result: you sent a secret, the recipient received it, and there's nothing left to find.
A concrete workflow for contractor onboarding
Here's how to structure credential handoff without creating a paper trail:
- Create one note per credential type. Don't bundle your AWS key, your Stripe key, and your database password into a single note. Separate notes mean you can rotate individual credentials later without wondering which combined note to invalidate.
- Set a short expiration window. If you expect the contractor to read the note within the hour, set it to expire in two hours. A note that expires unused is safer than one that sits open indefinitely.
- Send the link over the lowest-stakes channel available. The link itself reveals nothing — the secret is encrypted and the key is in the fragment. Slack or email is fine for the link. The channel's retention policy no longer matters because the link is worthless after first read.
- Confirm receipt out of band. Ask the contractor to confirm they opened it via a quick message or call. If they say they never received it, the link hasn't been read yet and you can generate a new one. If the link shows as already opened but they say they didn't open it, that's a signal worth investigating.
- Rotate on offboarding. This step is non-negotiable regardless of how you shared the original key. One-time links reduce ambient exposure during the engagement; rotation closes the loop when the engagement ends.
Where this approach fits in the broader tools picture
One-time links aren't a replacement for a password manager or a secrets manager like HashiCorp Vault. They're a transport mechanism — a way to get a secret from your possession into someone else's without leaving a copy in transit. Once the contractor has the key, they should store it somewhere sensible on their end.
If you're managing credentials for a whole team rather than a single contractor, it's worth reading about secure ways to share login credentials with team members — the considerations shift when you need ongoing access rather than a one-time handoff.
For longer engagements where a contractor needs to rotate or re-access a credential, a shared vault entry is more practical than a series of one-time notes. But for the initial handoff — the moment of highest risk, when a secret crosses from you to someone outside your organization — a self-destructing note is the right tool.
The thing most people miss
Most credential leaks from contractor relationships aren't the result of malice. They're the result of a key sitting in a place that seemed temporary but turned out to be permanent. The contractor didn't intend to leave it there. You didn't intend for it to stay. Nobody made a bad decision, exactly — but the default behavior of every normal communication tool is to keep everything forever.
The fix isn't a policy document telling people not to share keys over Slack. It's making the secure path as frictionless as the insecure one. Composing a note and sending a link takes about thirty seconds. That's the comparison you're working with.
Try it before your next contractor starts
The next time you need to hand off an API key, a database credential, or a private token, skip the DM. Compose a self-destructing note on SecureNotes — no account needed — and send the link instead. The key reaches its destination, then disappears. That's the whole point.