How it works
From raw audit logs to reconciled evidence
A collector inside your network reads what agents report and what your systems of record recorded, and minimizes it before anything leaves. The control plane rebuilds every run, links each claim to independent evidence, and turns it into mandates, scorecards and exceptions.
Architecture
Two planes, one contract
Collection happens where your data lives. Analysis happens in an EU-hosted control plane. Exactly one data shape — the canonical event — may cross between them, and both sides validate it against the same schema.
- OpenTelemetry GenAI spans
- Vendor platform exports
- Coding agent telemetry
- ERP change documents
- CRM and HRIS audit trails
- Mailbox and workbook logs
- Approvals and payments
- People
- Service principals
- Technical accounts
- Adapters→
- Normalize→
- Resolve identity→
- Minimize→
- Validate→
- DLP scan→
- Outbox
mandates
The collector and the ingestion API validate against the same JSON Schema. Unknown fields are rejected, not passed through.
Raw records, credentials, the hash salt and the identity map stay in your network. The control plane can join on hashed keys but can't reverse them.
Agents keep their native connectors, vendor platforms and APIs. ThetaLayer reads what those systems already record.
The pipeline
Seven steps from raw record to decision
Steps one to three run in the collector, inside your network. Steps four to seven run in the control plane.
Step 01 · Collect
CollectorRead-only adapters, inside your network
Small, versioned adapters read the native exports and audit logs your systems already produce, using read-only credentials that never leave your network. Nothing is installed in your agents.
- Agent runtimes: OpenTelemetry GenAI spans from in-house orchestrators; session, activity and billing exports from vendor agent platforms
- Systems of record: ERP change documents and payment runs, CRM and HRIS audit trails, mailbox and workbook audit logs, approval tasks
- Directory: people, service principals and technical accounts, for identity resolution
- invoke_agent spanrun.started · run.completed
- chat spanmodel.call — model, tokens, price reference
- execute_tool spantool.call — tool, operation, result
- Vendor session exportrun.* · tool.call · credits on completion
- Billing export linecost.allocated — platform fee per month
- ERP change documentapp.audit — erp.invoice_posted, erp.vendor_updated…
- Approval taskapproval.requested · approval.decided
- Payment runoutcome.updated — paid, blocked or reversed
Step 02 · Normalize
CollectorOne canonical event contract
Every record becomes one of nine event types with the same fields for agent, run, actor, tool, object, action, cost and outcome. Identities are resolved against your directory and kept apart: the person who asked, the credential that acted, and the type of principal.
- Deterministic event IDs, so re-sending an export never duplicates evidence
- Timestamps converted to UTC; amounts parsed from local formats — “12.450,00” becomes 12450.00
- Unresolved identities kept as raw and flagged, never guessed
- initiating_user_idWho asked?person:p_kbauer
- effective_identityWhose credentials acted?agent:ap-intake-de
- identity_typeWhat kind of principal?agent_service_principal · delegated_user · user · system
Step 03 · Minimize
CollectorHash or drop, before anything leaves
Sensitive values are replaced with keyed hashes or dropped before an event is queued for sending. Every event passes four gates on the way out, and every transformation is listed on the event itself.
- Adapter-level minimization
- Attribute allow-list — anything not on it is dropped and recorded
- JSON Schema validation with
additionalProperties: false - Outbound DLP scan — an email address or IBAN pattern anywhere blocks the event
- Supplier invoice numberinvoice_key: inv_3f9c2a71…hashed
- IBAN on a vendor recordnew_value_hash: iban_9a1f07c3…hashed
- Internet message IDmessage_ref: msg_5c0e18b2…hashed
- Recipient email addressrecipient_domain onlymasked
- Email subjects and bodies—dropped
- Spreadsheet cell values—dropped
- Approval comments, ERP item texts—dropped
- Raw tool arguments and results—dropped
Hashes are keyed (HMAC-SHA256) with a salt that stays in your network. The same IBAN always produces the same hash — so reuse across vendors is detectable — but the value can't be recovered.
Step 04 · Reconcile
Control planeRebuild every run. Link every claim to evidence.
Events are grouped into runs, sub-agent runs attach to their parents, and late evidence — approvals hours later, payments days later — is attached when it arrives. Each write an agent claims is matched to what the system of record recorded, with an explicit link method and confidence.
- Confirmed
- The system of record shows the change.
- Unconfirmed
- The agent reported success; no matching record exists.
- Contradicted
- The agent reported a failure or timeout, but the change happened.
- Unattributed
- An agent's identity changed data with no run behind it.
The tool result returned the record's ID — a document number, row or task ID.
A hashed key such as vendor + supplier invoice number, within a time window.
Identity and timing only. The weakest method.
- −25 ptsThe record's identity disagrees with the runtime's
- −10 ptsThe agent acted on delegated human credentials
- Max 50%Several records match equally well
Step 05 · Evaluate
Control planeVersioned mandates, applied to all history
Mandates are versioned rules per agent: allowed tools, approval thresholds, sensitive fields, spend caps per run and per month, and identity rules. The active version is checked against every run in the evidence store — so a rule change shows its impact on history before anyone enforces it.
- 9 toolsAllowed toolstool_allowlist
- > €10,000Approval above thresholdapproval_threshold
- bank_accountSensitive field changes need approvalsensitive_field
- €2.50Spend cap per runspend_cap_run
- €450 €650Monthly spend capspend_cap_month
- requiredActs under its own identityidentity_mode
Step 06 · Measure
Control planeMetrics with published definitions
Scorecards compare agents, versions, teams and task types on the same definitions. Every number drills down to the runs and records behind it. Allocated costs are labeled as allocated, and modeled savings as modeled.
- Cost per completed workflowΣ workflow cost of all runs ÷ completed workflows
Workflow cost = metered + allocated + delegated sub-agent runs. Failed and escalated runs still count.
- Straight-through rateruns completed with no approval and no takeover ÷ all runs
- Takeover rateruns escalated to a person, or failed ÷ all runs
- Evidence coverageruns with every claimed write confirmed ÷ runs with claimed writes
- Mandate compliancepassed checks ÷ (passed + failed checks)
Warnings, such as a delegated identity, are reported separately.
Step 07 · Review
Control planeExceptions with owners and an audit trail
Findings land in a review queue with severity, the full evidence chain and a playbook. Decisions are keyed to a stable exception ID, so they survive reprocessing, and every decision is written to an audit log with who made it and when.
- Confirm, dismiss or escalate to the agent's owner
- Decisions kept when evidence is reprocessed or a mandate changes
- Mandate versions and review decisions are both audited
- 21 Oct 09:14k.bauerConfirmed issueDuplicate posting · DE01-5100012345
- 21 Oct 09:20k.bauerEscalated to ownerBank account reuse · V100234
- 21 Oct 09:31m.weberDismissedUncertain link · documented exception
The contract
What a canonical event looks like
This is the only shape of data that leaves your network. Here, an agent claims it posted a supplier invoice. Nothing in the event reveals the invoice number, and nothing carries free text from your systems.
- 1Three identities, kept apart
Who asked, whose credentials acted, and what kind of principal that was. A delegated human token is never mistaken for an agent.
- 2The claim
The agent says it posted DE01-5100012345. The control plane looks for that change document in the ERP's own log.
- 3A business key, not the invoice number
invoice_key is a keyed hash of vendor and supplier invoice number. It joins ERP, approvals and payments without exporting either.
- 4Every transformation declared
Tool arguments and results never leave your network. What was hashed or dropped is listed on the event itself.
- 5Provenance to the raw record
Collector, adapter version and a SHA-256 digest of the source record, so any number can be traced back and verified.
1{2 "schema_version": "1.0",3 "event_id": "evt_47716034f59c4c513bbfd6299c6d37fb",4 "tenant_id": "nordwind",5 "source_system": "agent_runtime.orchestrator",6 "event_type": "tool.call",7 "occurred_at": "2026-10-06T08:14:03.120Z",8 "agent": { "agent_id": "ap-intake-de", "agent_version": "2.4.0" },9 "run": { "run_id": "run_0be9b581c4a3…", "step_id": "b7fdabaa6c80…" },1 "actor": {11 "initiating_user_id": "person:p_kbauer",12 "effective_identity": "agent:ap-intake-de",13 "identity_type": "agent_service_principal"14 },2 "tool": { "tool_id": "erp.post_invoice", "operation_class": "write" },16 "object": { "system": "erp", "type": "invoice_doc", "ref": "DE01-5100012345" },17 "action": { "result": "success", "external_ref": "DE01-5100012345" },3 "attributes": {19 "invoice_key": "inv_3f9c2a71d04e8b65",20 "vendor_ref": "V100234",21 "amount_eur": 12450.0022 },4 "redactions": [24 { "field": "supplier_invoice_number", "action": "hashed" },25 { "field": "gen_ai.tool.call.arguments", "action": "dropped" },26 { "field": "gen_ai.tool.call.result", "action": "dropped" }27 ],5 "provenance": {29 "collector_id": "col-nordwind-fra-01",30 "adapter": "orchestrator_spans", "adapter_version": "0.1.0",31 "raw_digest": "sha256:1830200e7e21…"32 }33}Demo environment · simulated data · values shortened with …
Rollout
Read-only first. Enforcement where you choose.
Detection comes before control. Enforcement is added later, at specific tool boundaries, once the evidence shows where a control pays for itself.
- PilotStage 1Observe
Read-only access to one agent runtime and two or three systems of record. Every run reconstructed, cost per outcome baselined, exceptions surfaced with evidence.
Breaches are found after the fact — and reported as such.
- PilotStage 2Draft mandates
Write mandates with each agent's owner and re-check them against history. Tune thresholds and caps on real data without blocking any work.
Every rule's impact is visible before it's enforced.
- LaterStage 3Enforce at chosen boundaries
Add enforcement only where a control earns it — for example, holding invoice postings above the approval threshold, or bank-detail changes without an approved request.
Scoped per tool boundary with you; not part of the read-only pilot.
FAQ
Technical questions
More on data handling, hosting and subprocessors is on the security page.
Do we have to change our agents or route traffic through a proxy?
What exactly leaves our network?
What if an agent platform doesn't return run IDs or document numbers?
How do you handle agents that act with a person's credentials?
Is this real-time?
How are costs calculated when vendors bill in credits, fees or seats?
Book a Demo
Watch a real run get reconstructed.
In 30 minutes we'll walk one workflow end to end — the raw evidence, the links and their confidence, the mandate checks and the cost per outcome — and scope a six-week, read-only pilot around your agents.