Security teams keep finding agents nobody declared. The discovery category reports the same shape over and over: a process in production calling a model provider on a loop, with no deployment record and no source in the repository, running for days or weeks before anyone notices. Every traditional tool needs something to scan. An undeclared agent leaves nothing behind.
Asqav does not detect these agents. A signing service only sees workloads that sign, and an undeclared agent never volunteers. That is worth stating plainly, because the claim that usually follows in this category is overstated.
What receipts actually change
Detection tools answer "what is running". Receipts answer a different question: what did the agents you know about do, and can you prove it to someone who does not trust your logs. When an unknown agent turns up, the team with receipts clears its governed set fast. Every registered agent carries a signed, tamper-evident record of its actions. The investigation stops being forensics across every workload and becomes a diff. Here is everything we can prove. This one thing is what we cannot.
The inversion, and its precondition
There is a stronger claim available: if every legitimate agent signs, the unsigned one is the anomaly. That claim is true under exactly one condition. Signing has to be enforced at a network chokepoint. Without the chokepoint, an undeclared agent calls the provider directly and your receipts say nothing about it. With the chokepoint, unsigned LLM egress either fails or lands in a log you control: the firewall deny for anything that went around the shim.
You can build that chokepoint today with components Asqav ships. Three steps.
Step 1: put a signing shim in the egress path
The shadow AI shim co-locates with your existing egress proxy. Workloads point their OpenAI or Anthropic SDK base URL at it through one environment variable, and the shim signs a SHA-256 of each request body before forwarding the original bytes upstream. Raw prompts and outputs stay inside your network. Each captured call produces a receipt with action_type="llm:egress".
pip install "asqav[cli]"
asqav shadow-ai init
asqav shadow-ai up
If your egress logs already flow into a SIEM, Asqav also accepts forwarded LLM egress rows and mints observation receipts from them, a passive complement to the inline shim.
Step 2: deny direct provider egress at the firewall
This is the part most teams skip, and it is the part that makes the inversion true. Add a network policy that denies direct egress to model provider endpoints from everything except the shim's egress address, default-deny if your network allows it. A provider you forgot to list is a hole in the chokepoint. The shim becomes the only sanctioned road out. A workload that routes through it leaves a receipt. A workload that tries to go around it hits the deny rule, and the attempt shows up in the firewall log instead of disappearing into normal traffic.
Step 3: choose your failure mode deliberately
The shim defaults to fail-open: if the signer is unreachable, the request still goes through and the failure is logged. That is the right default for availability, and the wrong one for enforcement. Set ASQAV_FAIL_OPEN=0 and the shim blocks the upstream call when it cannot reach the signer. Fail-closed plus the firewall rule closes the silent paths: traffic that avoids the shim hits the deny rule, and traffic through the shim cannot proceed when the signer is down. A sign call the API rejects is the remaining case, and the shim logs its status code.
What this setup honestly gives you
Receipts from one shim deployment sign under a single agent identity. They prove that governed LLM egress happened, when, and with which payload hashes. They do not attribute individual calls to individual registered agents, and they do not cover personal devices that bypass the corporate egress path. That remains a DLP problem. What you get is a hard boundary: inside the chokepoint, every model call leaves evidence, and anything that avoided the chokepoint is visible as a firewall deny.
From there, reconciliation is routine. Pull your registered agents from GET /api/v1/agents, export the signed activity window from GET /api/v1/export/csv, and compare against your own egress logs. Flows with no matching receipt bypassed the governed path. Registered agents with no receipts have gone quiet and deserve a look. The docs walk through the exact steps.
The missing artifact, inverted
Undeclared agents survive because there is no artifact to correlate. A governed agent's receipt can carry the opposite: four optional fields, executable_hash, sbom_digest, slsa_provenance_pointer, and supply_chain_pointer, bind the signed action to the exact build that performed it. When an incident responder asks "which build did this", the receipt answers with a digest instead of a guess. The build provenance docs cover the wire format.
Receipts do not find shadow agents. Detection tools own that problem, and plenty of them are competing for it. Receipts provide the other half: verifiable evidence of what the governed set did, and, behind an enforced chokepoint, the property that unsigned LLM egress is either blocked or logged. At that point the unsigned agent stops being invisible. It becomes the incident.