Direct answer: You almost certainly do not know, and access controls will not tell you. Permissions govern which systems an agent can reach, not what it puts into a prompt once inside them. What leaves your environment is the request payload: prompt text, retrieved files, tool-call arguments. Reading that outbound stream is the only way to know.


I ask security leads a version of the same question and get a version of the same answer. What is your team sending to OpenAI and Anthropic right now, in the prompts, at this moment. The confident ones point me to their access policy: agents can read this repository, call that internal API, touch these buckets. That is a real and useful control, and it is an answer to a different question than the one I asked. It describes where an agent is allowed to go. It does not describe what the agent writes down and ships to a third party once it gets there.

The gap between those two questions is the whole subject of this post, so it is worth naming precisely. I think of the request as having two layers. The first is reach: the set of systems, files, and APIs the agent is permitted to touch, which is exactly what your permission model defines and enforces. The second is payload: the actual bytes that leave your network on each request to the provider, the assembled prompt plus context plus tool arguments. Your controls are dense at the reach layer and dark at the payload layer, and the payload layer is the one that crosses your boundary.

How does a secret end up in a prompt?

Consider how a coding agent assembles a single request, because the mechanics are where the exposure lives. The agent reads a task, pulls in files it judges relevant, maybe runs a shell command whose output it captures, maybe calls a retrieval tool that returns a chunk of a config file. All of that gets concatenated into a prompt and posted to the provider. Every step there was inside your permission grant. The agent was allowed to read the file, allowed to run the command, allowed to call the tool. And the concatenated result on its way out the door contains a database URL with an embedded password, because that password happened to sit in the config file the agent was correctly permitted to read.

Nothing in that sequence was a policy violation, which is what makes payload exposure different from the breach you are used to defending against. There is no attacker, no exfiltration, no misconfigured bucket left public. There is a permitted agent doing permitted things, and a secret riding along inside a legitimate request because context assembly is indiscriminate by design. The agent's job is to gather anything that might be relevant. It has no concept of what is sensitive, so it forwards the AWS key in the environment dump and the customer email in the log line with the same neutral efficiency it forwards everything else.

Does our no-training agreement cover this?

This is where the "we hold an enterprise agreement, they do not train on our data" reassurance stops covering the actual risk. Non-training terms address what the provider does with your data after they receive it. They do nothing about the fact that a live credential is now sitting in a request log on infrastructure you do not run, readable by a support process you cannot see, and valid until someone on your side rotates a key they do not yet know was sent. The contract governs the provider's behavior. It cannot un-send the secret.

Where do I actually look to see what we send?

So the question moves from policy to instrumentation. If the exposure lives in the payload, you have to read the payload, which means putting a lens on the data path itself rather than on the access list. Most teams already have the vantage point and have not pointed it at this. If your traffic to model providers runs through a gateway or proxy such as LiteLLM, every request passes through one place before it leaves. If your agents and SDKs emit OpenTelemetry spans, the prompt and tool-call arguments are already being described in structured form. The stream you need to inspect is one you are very likely already producing and simply not scanning.

The gateway is the stronger vantage of the two, and the reason is worth understanding before you commit to an approach. A per-tool or per-SDK integration scans only the traffic from the tools you remembered to wire up, and the exposure you most want to catch tends to come from the agent someone spun up last week that nobody registered. A gateway sits on the network path itself, so every request bound for a provider passes through it whether or not the tool that sent it was on anyone's list. Scanning at the chokepoint gives you coverage that does not depend on an inventory staying current, and inventories of AI tools inside an engineering org never stay current for long. OpenTelemetry complements it by carrying the richer per-span context once you know which requests to look at.

Scanning it well is a detection problem with a shape worth understanding before you buy or build anything. Raw prompt text is noisy, so a flat search for the word "password" drowns you. What earns attention is pattern-matched detection of the things that actually hurt when they leave: credential formats, API-key shapes, private keys, tokens, and the personal-data patterns your obligations care about. Then each finding needs a severity, because a live production database credential in an outbound prompt is not the same event as a test fixture, and a queue that ranks them lets a small team work the top of the list instead of the whole firehose. Detection without ranking just relocates the overload.

How do I make a finding actionable?

A finding is only actionable if you can trace it, which is the last and most operational piece. Knowing that a secret was sent is a fire alarm with no address. What lets you respond is the request context around it: which session produced the prompt, which workflow or agent assembled it, and which person or team owns that workflow. That trace is what turns "something leaked" into "the migration agent on the payments team sent a live DB credential in session 9c2 at 14:07, rotate that key and fix that config." The point of the attribution is remediation, not judgment of the individual. You are locating a leaky pipe, not auditing a person's keystrokes.

We built Oberhahn to read that outbound stream from the gateway and telemetry you already run, flag credentials, keys, and sensitive data in prompts and tool calls before they reach a provider, rank them by severity, and trace each back to its session, workflow, and team. You can see the security card working against sample data in the demo before you connect a single real source.

The honest framing to hold onto is that this data proves what left your environment, and only that. It shows a credential appeared in an outbound payload, which session it came from, and how severe it is. It stops short of intent, stops short of proving the provider mishandled anything, and stays clear of monitoring what your engineers type. What it gives you is a smoke detector on the one pipe that carries your context to a third party, and right now, for most teams, that pipe runs with the lights off.


Frequently Asked Questions

How do I know what my team is sending to OpenAI or Anthropic?

You have to inspect the request payload, not your permission settings. Access controls define which systems an agent can reach; the prompt, retrieved files, and tool-call arguments are what actually leave your network. Route that traffic through a gateway or read your OpenTelemetry spans and scan the outbound content for credentials, keys, and sensitive data before it reaches the provider.

Can secrets end up in AI prompts even with strict permissions?

Yes, and strict permissions are exactly the condition under which it happens quietly. An agent permitted to read a config file will forward whatever is in that file, including an embedded database password, because context assembly gathers anything relevant and has no concept of sensitivity. No policy was violated, which is why access controls alone never surface it.

Does an enterprise no-training agreement protect us here?

It protects you from one thing, which is the provider training on your data. It does nothing about a live credential now sitting in a request log on infrastructure you do not run, valid until you rotate the key. The contract governs what the provider does after receiving your data. It cannot prevent the secret from being sent in the first place.

How do I find sensitive data in outbound prompts without reading everything?

Use pattern-matched detection for credential formats, key shapes, tokens, and personal-data patterns, then rank findings by severity so a live production secret rises above a test fixture. Trace each finding to the session, workflow, and team that produced it so you can rotate the key and fix the source instead of just knowing something leaked.