Security hygiene
Redact secrets before you paste into AI
Every week, someone pastes an .env into a chat. This guide is the boring discipline that prevents that story from being yours.
What counts as a secret
- API keys, tokens, session cookies
- Private keys and keystore files
- Passwords and connection strings
- Personal data you would not post on a public issue tracker
Workflow
- Copy text to a scratch buffer, not straight into the model.
- Search for
sk-,ghp_,Bearer,BEGIN PRIVATE,password=. - Replace with placeholders like
[REDACTED_OPENAI_KEY]. - If using agents that pack logs, run a redaction step (for example context-guard style tools) before model inject.
- Rotate any key that might have been exposed, do not debate; rotate.
Agent-specific rules
Never ask an agent to “read all env files and fix deploy” without a allowlist. Prefer examples with fake credentials. Continuum claims should hash files, not embed secret needles.
What can leak, and where
A secret rarely leaks because someone decided to publish it. It leaks because it was sitting in the thing that got copied: a log line, a screenshot, a config snippet, a stack trace, a URL with a signed token. The first step is to stop thinking of the prompt as the only place a secret can travel.
| Channel | What can travel with it | Practical control |
|---|---|---|
| Prompt or chat history | Anything you paste, plus attachments and screenshots | Scratch buffer first; never paste an unredacted config |
| Provider retention | Chat logs, abuse-review copies, workspace history | Assume the prompt is retained; redact before sending |
| Agent file access | Every file the tool can read, including .env | Allowlist paths; least privilege; no “read the whole repo” |
| Tool output | Paths, hostnames, tokens echoed from the environment | Read the output before feeding it to another model |
| Clipboard and extensions | Clipboard managers, browser extensions, sync history | Clear clipboard; avoid sensitive copy on shared machines |
| Screenshots | Open tabs, notifications, keys in a terminal | Crop, cover, and re-read the image before sending |
What counts as a secret
“Secret” is broader than an API key. Use the test: would this value let someone act as you, find a private system, or identify a person who did not consent to being in the prompt?
| Category | Examples | What to send instead |
|---|---|---|
| Credentials | API keys, OAuth tokens, session cookies, passwords | [REDACTED_API_KEY], [REDACTED_TOKEN] |
| Private keys | SSH keys, signing keys, keystore files | Never paste; describe the key type only |
| Connection data | Database URLs, connection strings, internal hostnames | postgres://[USER]:[PASS]@[HOST]/[DB] |
| Personal data | Email addresses, phone numbers, addresses, customer names | Roles: [CUSTOMER_A], [EMAIL] |
| Private URLs | Signed URLs, admin panels, unlisted documents | Origin plus path shape, query removed |
| Logs | Tokens in headers, file paths with usernames, IPs | Only the relevant lines, values replaced |
| Business data | Prices, unreleased plans, contracts, private metrics | Ranges or labels, not the exact figure |
The five-minute workflow
- Copy to a scratch buffer, not the chat. A local editor gives you a place to search and edit before anything leaves the machine.
- Scan for known shapes. Search for
sk-,ghp_,xoxb-,Bearer,BEGIN PRIVATE,password=,token=, and your provider’s key prefix. - Replace the value, keep the shape. A placeholder that preserves the format is easier for the model to reason about than a missing field.
- Trim the context. Remove unrelated lines, other customers, and anything the task does not need. The safest data is the data you did not send.
- Read it as if it were public. If the buffer were posted on a public issue tracker, would you be comfortable? If not, keep editing.
Good and bad redaction
| Bad | Why it fails | Better |
|---|---|---|
API key: sk-live-9f... | The prefix and several real characters remain | API key: [REDACTED_OPENAI_KEY] |
password= with the value deleted | The model cannot tell whether the field is empty or withheld | password=[REDACTED] |
| A screenshot with the key blurred by a thin marker | The underlying pixels may still be recoverable | Crop the region out, or take a new screenshot without the key |
| A full log with one token replaced | Other lines still contain paths, emails, and IPs | Keep only the error lines the task needs |
| A real customer name replaced in one place | The same name appears later in the thread | Replace every occurrence with a stable role label |
Special cases
Logs
Logs are the most common leak because they are copied whole. Keep the timestamp, level, and the one error line that matters. Remove request headers, cookies, query strings, usernames, internal paths, and anything that identifies a customer. If the task needs the sequence, number the lines instead of pasting the raw file.
.env files
Do not paste an .env file. Send the variable names and fake values, or a single redacted line. If the task is “why is this variable undefined,” the model needs the name and the loading order, not the secret.
Screenshots
Check the edges, the tab bar, the notification area, and the terminal prompt. A key can be visible in a window you forgot was open. Crop the image, do not rely on a blur brush.
URLs
Remove the query string unless the query is the subject. Signed URLs, ?token=, ?key=, and ?signature= are credentials. Keep the origin and path shape if the model needs to understand the route.
Stack traces
Stack traces can contain absolute paths with a username, environment variables, and request bodies. Keep the exception type and the relevant frames; remove the rest.
Agent-specific rules
- Allowlist, do not open the whole repo. Give the agent the files the task needs. A “read everything and fix deploy” instruction is a data exfiltration request with a friendly name.
- Least privilege. Read-only unless a write is required. No network unless the task needs it. No shell if a file read is enough.
- Hash, do not embed. If a receipt needs to identify a file, use a SHA-256, not the file’s contents. A Continuum claim should prove the bytes without publishing the secret.
- Redact tool output before the next model. A tool can echo an environment variable or a path. Treat every tool result as untrusted text.
- Keep a local gate. A small scanner for known key shapes catches the obvious cases before the prompt leaves the machine. It does not replace reading the text.
If a secret leaks
- Rotate or revoke first. Do this before deleting the message, before apologizing, and before investigating. A live key is a live risk.
- Check usage. Look at the provider’s audit log, billing, and recent requests. If the key could act, assume it may have.
- Remove the public copy. Delete the message, edit the issue, remove the screenshot, clear the clipboard. Deletion is cleanup, not containment.
- Notify if required. Follow the provider’s and your organization’s incident process. Do not hide a leak to avoid embarrassment.
- Write down the cause. Which channel, which value, which control failed. Fix the control, not just the instance.
The order matters. A deleted message with a live key is still a live key. Rotate first.
Pre-flight checklist
- [ ] I copied to a scratch buffer, not straight into the chat.
- [ ] I searched for key prefixes, bearer tokens, private-key headers, and password fields.
- [ ] Every secret is replaced with a labeled placeholder that preserves the shape.
- [ ] Customer names and emails are replaced with stable role labels.
- [ ] Query strings and signed URLs are removed unless they are the subject.
- [ ] Screenshots are cropped, not blurred.
- [ ] The agent has an allowlist, not the whole repository.
- [ ] I read the final text as if it were public.
FAQ
Is it enough to delete the message after pasting?
No. The provider may retain logs, the browser may cache the text, and a screenshot may exist. Rotate the credential first, then clean up.
Can I use a fake key that looks real?
Use an obviously fake value such as [REDACTED] or example-key-not-real. A realistic-looking fake can be mistaken for a live key and may trigger scanner alerts.
What about a local model?
Local reduces the number of copies that leave the machine, but it does not remove logs, clipboard history, or screenshots. Redact for the same reason.
Do I need a special tool?
A text editor with search and a short list of key prefixes is enough to start. A scanner helps with volume; it does not replace the final read.
What if the secret belongs to a customer?
Do not paste it at all. Use a role label, and follow your incident process if it was exposed. The customer’s data is not yours to trade for a faster answer.