An audit log is only useful if you can trust two opposite things about it: that it captured what happened, and that it did not quietly capture more than you asked for. Meandr’s log is built around that tension. By default it records the metadata of every call and the contents of none.
Metadata by default: one row per call
Every resolved tool call becomes one immutable row. A row is small — on the order of a couple of hundred bytes — and it answers the questions an audit asks:
- Who — which agent made the call, and the caller’s IP it came from;
- What — which server and tool, and the method;
- When — the time and how long it took;
- Which rule — the policy that decided it, the verdict (allow, deny, or approve), and a short reason code;
- Outcome — the status, and how many bytes flowed each way.
Crucially, that row carries no request or response body. It tells you a refund tool was called, by this agent, matched by that rule, and denied — without keeping a copy of the refund itself. This per-call metadata log is the real, running surface: it is what powers the call timeline and the denial feed, and it holds for denied calls exactly as for allowed ones, so “we blocked this” is always on the record.
The verdict codes are worth knowing, because they also drive billing. A call is billable only if it actually reached the upstream — a success or an upstream error — while policy blocks, approval holds, and rate-limit or quota blocks reached nothing and cost nothing.
Contents only when you ask: capture per rule
Sometimes you do need the payload — to debug an integration, or to satisfy a compliance requirement that the actual request be retained. Capture is therefore a setting on the rule, not a global switch. Each policy carries a capture value:
meta— the default; store nothing but the row above;request— keep the call’s arguments;response— keep what came back;both— keep both.
Because capture follows the same first-match rule as every other policy field, “capture everything except payroll” is expressible: a meta rule on the sensitive path genuinely stores nothing, while a broader rule captures the rest. It applies to denials too, so a blocked call can keep the very payload it was blocked on — which is exactly what makes “we stopped this” auditable.
Payload-blind by design
When a body is captured, it is encrypted before it leaves the proxy with AES-256-GCM, under a data key wrapped by a per-environment KMS key. The proxy holds the encrypt path; the backend holds the decrypt role and uses it only inside a controlled, authorized “show this request” view — never at rest, never in bulk. The bytes sit encrypted until a person with permission opens one specific record.
And Meandr does not read them. Capture is storage, not inspection — there is no DLP, no regex, no PII scanning over your traffic. That is a deliberate guarantee, not an omission: adding content inspection would break payload-blindness, so it is off by architecture. For a privacy-sensitive buyer the story is clean — Meandr cannot read your traffic even when you have asked it to retain it.
These capture guarantees describe how the system is designed and how the custody works; the metadata log is the piece running as your day-to-day audit surface today.
Retention as a plan axis
How long a captured body lives is a retention class that travels with the object as a storage tag rather than something bolted on later — a shorter window on the entry plan, a longer one on Business. Retention is priced as its own axis, so you keep bodies as long as your obligations require and no longer. See the pricing page for how the tiers line up.
Set the capture field when you write your first policy, and read how a held call becomes a logged human decision.