← The ADLC library
Governance & security · 7

Prompts, context, and the leak surface that did not exist before

Data loss prevention was built around files moving and people sending them. Agentic development creates a channel that looks like neither, carries more context than anyone intends, and is largely unmonitored.

The models organisations use to think about data leaving are older than they look. They assume a person, an intent, and an artefact: someone attaches a file to an email, uploads to a personal drive, copies to a USB device. Controls are built accordingly, watching for documents in motion and for people doing the moving.

Agentic development produces a channel that does not match that shape at all. There is no file. There is often no person present at the moment of transmission. The content is assembled automatically from sources nobody chose one by one, and the volume is high enough that human review of what went out is not available even in principle.

I do not think this is a crisis, and I want to be careful not to write the breathless version of this argument. But it is a genuinely new surface, and the controls that cover it are not the controls most organisations already have.

What actually goes out

Start concretely. When an agent works on a task, what is in the request?

The instructionWhat someone asked for. Usually benign, occasionally contains customer names or an incident description.
Retrieved codeThe files the agent decided were relevant. Nobody chose these individually and the selection is not reviewed.
Surrounding contextConfiguration, schemas, environment files, test fixtures. Test fixtures are where real data hides.
Tool outputCommand results, logs, stack traces, query output. The highest-risk category and the least considered.
Conversation historyEverything from earlier in the session, resent with each turn. Exposure compounds across a long task.
Five sources. Only the first is chosen deliberately by a human, and the two most dangerous are assembled automatically.

The fourth row is the one worth dwelling on. An agent debugging a failing integration test runs the test, and the failure output contains a response body. If that test hits a staging environment populated from a production snapshot, which is extremely common, the response body contains real records. Nobody decided to send customer data to a model provider. Somebody decided to let an agent run the test suite, six months ago, and the data path was created as a side effect.

Test fixtures deserve the same attention. A fixture file that was quietly seeded from a production export years ago is now part of the retrieval corpus, and it will be sent whenever the agent looks at the module it belongs to.

Why classic controls do not reach it

There are several structural reasons the existing toolkit does not cover this well, and it is worth understanding them rather than assuming the security team is behind.

The traffic is API calls over TLS to an endpoint that is on the allow-list because it is supposed to be. There is no attachment, no unusual destination, and no anomalous volume, because the whole point of the tool is to send a lot of content to that destination all day.

The content is assembled at the moment of the call, from many small sources, none of which individually looks like a document. Classification systems built around files do not have an object to classify.

And the human is absent or nominal. An engineer typed a sentence and the system assembled forty files. Attributing intent, which most policy frameworks depend on, does not work cleanly.

The channel controls assume

  • A discrete file or message
  • A person choosing to send it
  • An unusual destination
  • Reviewable volume
  • Intent that can be attributed

The channel that exists

  • Assembled context with no file object
  • Automatic selection nobody reviewed
  • An approved endpoint, used constantly
  • Volume beyond any human review
  • Intent one step removed from the transmission
Not a gap in anyone's diligence. The channel simply does not have the properties the existing controls key on.

The controls that do work

Four things, roughly in order of how much they buy relative to what they cost.

Keep secrets out of the places agents read. This is the highest return by a wide margin, and most of it is work organisations already claim to have done. Secrets in environment files, in configuration committed to the repository, in fixtures, in the sample dotfile that has a real key in it because someone was in a hurry in 2023. Scanning for these is mature technology, and the difference now is that the exposure is continuous rather than contingent on someone browsing the repository.

Make sure test and development data is not production data. The single most common path by which real records reach a model provider is a staging environment seeded from production. This has always been a poor practice and it has always been tolerated because the alternative is work. The calculus has changed: the data is no longer merely sitting in a less-protected environment, it is being actively read and transmitted by tooling all day.

Bound the context. An agent that can read the entire repository will, given a sufficiently vague task, read a great deal of it. Scoping retrieval to the relevant paths reduces exposure and, separately, improves output quality. This is the rare control that pays for itself in performance terms, which makes it much easier to get adopted.

Record what was sent. Not necessarily the content, which creates its own retention problem, but the shape: which files were included, which tools ran, which endpoint received it, under whose identity, against which work. This is what lets you answer the question that will eventually be asked, which is not “is this safe” but “what did we send on the fourteenth.”

call:      bedrock://eu-central-1/anthropic.claude
work:      PLAT-4471   actor: agent://refactor-worker
included:  src/payments/{charge,refund,ledger}.ts   (3 files)
           test/fixtures/accounts.sample.json
tools_run: test:integration  -> 412 lines captured
flagged:   fixture matched pattern iban  (2 occurrences)
policy:    allowed, flagged for review
The record does not store the content. It stores enough to reconstruct what class of material was exposed, which is what an incident response or an audit actually needs, without creating a second copy of the sensitive data.

Injection, briefly, because it belongs here

The mirror image of leakage deserves a mention. Agents read issue descriptions, dependency documentation, code comments and web content, and any of those can carry instructions written by someone who does not work for you.

The defence is not detection, which is unreliable, but capability limitation, which is the subject of the least-privilege piece earlier in this series. If an agent cannot reach production data and cannot make arbitrary outbound calls, then an injected instruction telling it to exfiltrate has nowhere to go. The reason these two topics belong together is that leakage controls and injection controls are largely the same controls viewed from opposite ends: an egress allow-list stops both the accidental send and the deliberate one.

Where this breaks down

Content inspection at this boundary is expensive and mostly theatre. Scanning every assembled context for sensitive patterns adds latency to every interaction and produces false positives at a rate that trains people to click through. Pattern matching for high-confidence formats, such as key material and account identifiers, is worth it. General classification of “is this sensitive” is not, at this volume.

Recording what was sent creates a retention question. A log of which files went where is itself a map of your codebase and its sensitive areas. It needs the same protection as the thing it describes, and organisations sometimes create a new exposure while documenting an old one.

Bounded context fights the tool’s usefulness. Narrow scoping degrades quality for tasks that genuinely span the system, and engineers will widen it, correctly, when it blocks them. The equilibrium is a default that is narrow and an escalation that is easy and logged, which requires the logging to be trusted enough that people do not route around it.

None of this touches what the provider does afterwards. Everything here is about what leaves. Retention and training use are contract terms, unverifiable from the outside, and the piece on data residency in this series is the more relevant treatment of that boundary.

Local models change the exposure, not the discipline. Running inference inside the boundary removes the third-party question entirely and leaves the internal one, which is that an agent is still assembling and moving sensitive material across trust boundaries inside your own network. Several organisations have treated self-hosting as the end of the conversation. It is the end of one conversation.

The takeaway

Agentic development creates an egress channel with none of the properties existing controls key on: no file, no chosen destination, no reviewable volume, and a human whose intent is a step removed from the transmission.

The controls that work are unglamorous and mostly predate the problem. Get secrets out of what agents read. Stop seeding development environments from production. Bound retrieval to the work, which improves output anyway. Record the shape of what was sent, without keeping a second copy of it.

If you take one thing into next week: find out whether your staging environment contains real customer records, and if it does, work out how many times an agent has read them this month. That number is currently unknown almost everywhere, and it is knowable.

The next piece moves from the technical surface to the procedural one, and asks what change management means when the entity making the change is not a person.