Inference logs
The opt-in, metadata-only inference log: how to turn it on, every field a row holds, what is never recorded, and how to read it in the console and the API.
With inference logging on, the gateway writes one AiFirewallLog row per inference: the model, the policy decision, which rules matched, token counts and latency. It is off by default. Prompts and completions are never recorded, with logging on or off: the table has no column for them.
Turning it on
| Where | How |
|---|---|
| Resolve Platform | Inference logging card on the Overview tab of the AI Firewall page |
| CLI | vulnetix ai-firewall settings --logs (on), --no-logs (off) |
| Policy file | spec.settings.logsEnabled: true in .vulnetix/ai-firewall.yaml |
| Check | vulnetix ai-firewall status prints Inference logging on or off |
Turning it on needs a paid plan. The CLI API answers 403 inference logging requires a paid plan; the console answers with a plan-locked marker and the setting stays off. Turning it off is never gated. The gateway checks the plan again on every request, so an organisation that downgrades with the flag still on stops writing rows.
What a row holds
| Field | Value |
|---|---|
providerSlug |
Provider the request went to; workers-ai for evaluate calls |
model |
Model id as sent. Empty for a provider refusal, which happens before the body is read. |
decision |
allow, flag, redact or block |
blockedBy |
The blocking rule’s name, or provider_policy, provider_key_missing, model_policy, upstream_blocked, upstream_redirect |
violations |
JSON array of matched rules: policy_uuid, policy_name, rule_type, action, detail. Never the matched text. |
wire |
chat, responses, messages or kiro |
inspected |
How many text units the guardrails read. 0 against a non-empty rule set means the request was parsed but nothing in it was screened. |
statusCode |
Status returned to the client |
promptTokens, completionTokens |
From the provider’s usage report, when it sent one |
stream |
Whether the request streamed |
latencyMs |
Gateway to provider and back |
clientName, clientVersion |
The calling agent from its headers. Attribution, not proof. |
contextHash |
The capability set the request declared; joins to the inventory |
toolCount, mcpCount |
How many tools and MCP servers the request declared |
createdAt |
Epoch milliseconds |
count_tokens requests and refusals before the model is known (bad org, bad key, unknown provider, unparseable body) write no row. Provider refusals do, with an empty model.
What is never recorded
- Prompt or completion text, tool arguments or tool results.
- The text a guardrail matched or redacted.
- Request or response headers, including keys.
The gateway’s own operational log line for each request holds method, path, status and duration.
Where rows also go
While logging is on, each row is also forwarded, best effort, to Guardian, the Vulnetix SIEM, as a product_events row. Every capability the hold for review holds is forwarded too, whether or not logging is on. Rows wait in a bounded in-memory buffer and are dropped if a post fails; the database row stays the record. Guardian drops rows for organisations below its own plan. See the SIEM docs.
Reading logs
The console’s Logs page has an AI Firewall stream with decision charts, the top blocking rules, providers and clients, and a paged table. The range is 24h, 7d, 30d (default) or 90d.
Resolve Platform API, session-authenticated, under https://www.vulnetix.com/api/site/v1:
| Request | Parameters | Returns |
|---|---|---|
GET /ai-firewall/logs |
page (from 1), per_page (1 to 50, default 10), decision (allow, block, redact, flag), provider, client (unknown matches rows with no client), model (substring) |
{"entries": [...], "pagination": {"page", "perPage", "totalRows", "totalPages"}}, newest first |
GET /ai-firewall/logs/stats |
range (24h, 7d, 30d, 90d; anything else is 30d), provider, client, model |
buckets (hourly for 24h, daily otherwise, counts per decision), guardrails (top 8 blocking or redacting rules), providers, clients (top 8 each), totals (inferences, blocked, redacted, flagged, streamed, promptTokens, completionTokens, latencyP95) |
Rows exist only for the time logging was on.
Retention
No job in the gateway, the console API or the schema deletes AiFirewallLog rows. Rows are deleted with the organisation (ON DELETE CASCADE). There is no per-organisation retention setting.