You Cannot Unsend a Secret
// 2026-08-25 · Frederic Haddad · 9 min read
Three files. One unsendable message. Zero benefit.
That is the full accounting of a mistake I made on a Tuesday afternoon, in my own system, about ninety seconds after I got annoyed. A few months ago I published a post arguing that your AI agent should never hold your passwords — the charter model, permissions granted narrowly and revocably instead of handed over whole. I wrote the rule, then I broke it. This is what that looks like from the inside.
what happened — a simple task that wasn't
The goal was boring. I wanted to give an AI assistant SSH access to a second machine I run, so it could work there directly instead of me acting as a human clipboard between two terminals. Generate a key pair, put the public half on the target, keep the private half where it belongs. Ten minutes.
It took the better part of an hour and it never worked.
The confusion was over which side generates the key pair and where each half ends up. Trivial written down. In practice it took several rounds — a key generated in the wrong place, a public key pasted where it did no good, a permissions prompt on every attempt, then another attempt. Each round was individually reasonable. Collectively they built the specific low-grade irritation that makes a competent person do something stupid.
So I did the stupid thing. I pasted a plaintext username and password directly into the chat channel. Not into a vault. Not into an environment variable the agent could read without me seeing it. Into a message, in clear text. The reasoning, if you can call it that: just let it in, we'll deal with hygiene later.
Here is the part that still makes me wince.
It didn't even work. A hard tool-level safety gate blocked every outbound SSH attempt regardless of my explicit approval — it was not a permission I had the power to grant. We tried multiple automation routes around it. Every one refused. I handed over a live credential in plaintext for absolutely nothing.
the fan-out — where the password actually went
I assumed the damage was one message I could delete. The way that was wrong is the entire point of this post. When I went back to clean up, the password had already propagated into three separate files. It was in an automation script, written there during one of the failed attempts. It was in an archived working note, captured as part of a session summary. And it was sitting in a task-tracking database, embedded in the description of a to-do item about finishing the SSH setup.
I had not thought about any of those three at the moment I typed it. Not one. They were downstream artifacts of a normal AI workflow doing what it is designed to do: persist context, write things down, keep state. The system was not malfunctioning. Correct behaviour here means the secret gets copied.
I redacted all three. That part was fixable. The message was not. Deleted or not, it existed in a transcript, in logs, in whatever retention layer sits behind the platform — surfaces entirely outside my control. There is no unsend. There has never been an unsend.
And the SSH setup? Abandoned. I took a real risk and bought nothing with it.
the pattern is bigger than my bad afternoon
Around the same period I ran a routine AI-assisted documentation audit across a set of production repositories. Nothing security-related — just checking whether the docs still matched the code. It incidentally surfaced what appeared to be live API keys committed in plaintext in an environment file. It also found development database credentials sitting in a project's own instructions file — the document written specifically to be read by an AI assistant on every session.
Nobody put those there maliciously. They had simply been there a long time, added by someone solving a Tuesday-afternoon problem exactly like mine, then never removed because nobody was looking and nothing broke. That is the shape of almost every credential leak I have seen. Not an attack. Accumulated convenience.
The mental model people carry is: I'll paste it, the agent uses it, we move on. Three steps, one location, clean. The reality is that a secret entering an AI workflow immediately fans out into scripts, logs, notes, databases and transcripts — most of them invisible to you at the moment you type it. Cleanup is not a deletion. It is a search across a surface area you have no map of. Some copies are simply unrecoverable.
So the only safe rule is the harsh one: treat every secret that touches a chat channel as burned. Do not redact it. Rotate it.
the bitter irony worth sitting with
Look again at why I pasted the password. Not because the safety controls failed. Because they worked. The permission prompts, the approval gates, the tool-level SSH block — guardrails doing precisely their job. And their cumulative friction is what pushed a security-literate person into a workaround categorically more dangerous than anything they were preventing. The gate stopped an SSH connection. The frustration it produced put a live password into permanent logs.
This is the real lesson, and it applies far beyond AI. When guardrails are annoying, humans route around them, and the workaround is almost always worse than the risk the guardrail was built for. A control with no fast legitimate path through it does not eliminate risk. It relocates it somewhere you cannot see.
how to give an agent access without ever giving it a secret
Here is what I actually do now. None of it is exotic. All of it removes the moment where a human is tempted to paste.
Service tokens with narrow scopes, never account passwords. A password is an identity — everything that identity can do, forever, everywhere. A scoped token grants one capability on one resource. If it leaks you revoke one token, not your life.
Put the credential in the OS keychain, not the conversation. The machine the agent runs on already has a secure credential store. The right pattern is the agent invoking a tool that reads from it at runtime. You never see the secret. Neither does the transcript. Highest-leverage item on this list.
Prefer short-lived credentials. A token valid for one hour that leaks into a log is an incident with a deadline. A password valid for three years is a liability you will forget about long before an attacker does. Where an expiry can be set, set it aggressively.
One account per purpose. Give the agent its own user on the target machine with only the permissions its job requires. When something goes wrong you disable that account at 2am without taking down your own access — and the audit log tells you exactly which actor did what.
Build a fast legitimate path before you build the gate. If the secure route takes four minutes and the insecure route takes nine seconds, the insecure route wins under pressure. Every time. Make the safe path the quick path, or accept that your control is decorative.
if it already happened — the rotation checklist
For anyone reading this with a slowly sinking feeling:
- Rotate first, investigate second. Change the credential before you do anything else. Do not spend twenty minutes assessing exposure while the live secret sits in a log.
- Then search the fan-out. Scripts, config and environment files, session notes, task trackers, commit history, and any assistant instruction files. Assume at least one copy exists somewhere you did not expect — in my case there were three.
- Accept that sent messages are permanent. Delete them anyway, for hygiene, but never count that as remediation.
- Check the logs for use. Look for authentications from the window between exposure and rotation. Usually nothing. Look anyway.
- Write down the friction that caused it. The paste had a reason. If you fix the credential but not the reason, you will do it again in six weeks.
why this bites harder here
In the Gulf I work almost exclusively with lean teams — a founder and a handful of operators running real revenue, moving fast, wearing every hat. There is no security function. No second engineer whose job is to notice a password ended up in a task tracker. The person who pastes the credential is the same person who would have to catch it, and they are busy being three other departments that afternoon.
That is not a criticism. It is structural, and it means the margin for a quiet accumulated mistake is far thinner than inside a large organisation with rotation policies and secret scanning running by default. Meanwhile these same teams are adopting AI agents faster than almost anyone — at ten people, leverage is not a nice-to-have.
Speed plus no safety net. That is the exposure.
what I run as standard now
Every engagement now starts with a credential inventory before a single agent gets deployed: what secrets exist, where they live, which ones an assistant could ever encounter, and which can be replaced with a scoped token or a keychain lookup. About half a day. It has never once come back empty.
I also write the rotation checklist above into the operating docs of every system I build. The goal is not that nothing ever leaks — it is that when something does, the response is fifteen minutes of routine work rather than an afternoon of archaeology. The sibling incident, where I broke a different safety rule of my own and wrote up the receipts, is I Broke My Own Safety Rule.
If you are giving AI agents access to real systems and you are not certain where your credentials have already travelled, that half-day inventory is a cheap place to start. I made this mistake in my own system and paid for it, which is why the inventory exists — I'd rather you learn it from my receipts than your own. Book a consulting day or send me an inquiry first if you'd rather talk before booking.
I wrote the rule. Then I broke it. The least I can do is show you the receipts.