Redacting Secrets From Prompts Before They Leave Your Machine
Credentials reach model context through error output, config files and git history. Pre-send scanning, why gitignore is no defence, and rotating on suspicion.
A credential in a prompt is not the same class of problem as personal data in a prompt. Personal data creates an obligation you manage. A live API key creates an exposure you have to close, and the clock started when the request was sent rather than when you noticed.
The practical difference is that there is exactly one correct response to a suspected credential exposure, and it is rotation. Everything else in this article is about making that response rare rather than about avoiding it.
The paths credentials take into context
Error output is the leading one and the least expected. A failed HTTP call logged with its headers prints the authorisation header. A database connection error prints the connection string, password included. A misconfigured client dumps its whole config on startup. The developer copies the failure into a debugging prompt because the failure is the thing they need help with.
Configuration files are the second path, and coding agents make it worse. An agent asked to fix a startup problem will read the environment file, because that is where the answer usually is. It cannot tell a placeholder from a production credential, and it will include what it read in its next request.
Git history is the third and the most persistent. A key committed and then removed in a later commit is still in the object store, still in every clone, and still reachable by any tool that reads history rather than the working tree. Repository-wide search and blame walks find it immediately.
Then the incidental paths: a terminal screenshot pasted into a multimodal prompt with a key visible three lines up, a CI log where a masked variable was echoed inside a longer string, a notebook output that captured a token.
Gitignore is not a control here
A common assumption is that keeping secrets out of the repository via ignore rules keeps them out of prompts. It does not, and the reason is worth being precise about.
Ignore rules govern what git tracks. They say nothing about what exists on disk, and the file is still sitting in the working directory where every tool can read it. An agent with file system access enumerates the directory, not the index — an ignored environment file is fully readable to it. Agent file system access covers scoping that reach.
They also apply only from the point they were added, so a file committed earlier stays tracked and its objects survive regardless. Treat the ignore file as tidiness and put the real control where it can see the bytes leaving.
Scan on the way out
The control that works is a scan immediately before the outbound request, in the client or proxy every call already passes through. Scanning the source files is a losing game because there are too many sources; scanning the assembled payload is one place with one policy.
Detection is more tractable than for personal data because most credentials are designed to be recognisable. Provider keys carry distinctive prefixes and fixed lengths, private keys have literal header lines, JWTs have a recognisable three-segment structure that decodes, and connection strings follow a documented shape. A well-maintained pattern set catches the large majority of real leaks.
Add high-entropy detection for the rest and accept the false positives. A long random-looking string assigned to a variable named token or secret is worth flagging even when it turns out to be a fixture. Tuning that to zero noise tunes it past the point where it catches anything.
The important design decision is what happens on a match. Blocking the request is the right default for anything matching a high-confidence pattern. Redacting silently trains people to ignore the mechanism, and warning without blocking means the request goes anyway. Running traffic through a proxy gives you the single place to enforce it.
Rotation is the response, not investigation
When a credential may have been sent, the instinct is to work out whether it really was — check the logs, ask whether the provider retains that request, judge the likelihood.
That reasoning is backwards. Rotation is cheap and fast for almost every credential type. Establishing with confidence that a secret was not exposed is slow, frequently impossible, and the answer only ever reduces your uncertainty rather than eliminating it. Rotate first, then investigate at your leisure to understand the path.
What makes this workable is rotation being routine rather than an incident. If it requires a change request, a deploy window and three teams, people will quietly decide the exposure was probably fine. Secrets held in a manager and read at runtime turn a security decision into an ordinary operation.
Rotating issues a new credential; it does not always invalidate the old one. Confirm the previous value is dead, then check the provider's access log around the exposure window. Audit logging covers keeping that record on your own side.
Push it into CI so it is not a habit
Manual discipline degrades under deadline pressure, so the check has to be somewhere that does not depend on remembering. Two layers work well together.
A pre-commit hook catches the secret before it reaches history, which is the point where cleanup goes from trivial to painful. It runs on the diff, so it is fast enough to keep. Pre-commit hooks around model tooling covers wiring that up.
A CI job scans the full history on the default branch and fails the build on a finding, catching what the hook missed, what predates it, and what someone bypassed. Run it on a schedule too, since a new pattern can find something already there. Running model tooling in CI covers the pipeline shape.
Reduce what is reachable in the first place
Scanning is a filter on a problem you can also make smaller. An agent that cannot read the environment file cannot include it in a prompt, and no pattern set has to be correct for that case.
Deny-list the obvious credential locations in whatever file access policy your tooling supports, and inject secrets at runtime from a manager rather than leaving them in files an agent will walk past. Agent sandboxing covers scoping its view of the filesystem.
The working policy is short. Block on high-confidence patterns at the outbound boundary, hook plus CI so history stays clean, credentials in a manager and never in files an agent can reach, and rotate on suspicion without waiting for proof. The last one is the only part that has to be reflexive.
Common questions
Does gitignore stop secrets reaching a model?
No. Ignore rules govern what git tracks, not what exists on disk. An agent enumerating the working directory reads an ignored environment file normally, and anything committed before the rule was added stays in history regardless.
Should a scanner block the request or just redact it?
Block on high-confidence patterns such as known provider key prefixes and private key headers. Silent redaction trains people to ignore the mechanism, and a warning that does not block means the request goes out anyway.
What do I do if I think a key was sent in a prompt?
Rotate immediately, then investigate. Rotation is cheap and fast; proving a secret was not exposed is slow and usually impossible. Confirm the old value is actually revoked, then check the provider access log around that window.