Govern
Documentation

Version Latest

Request logs and observability

Turn on model gateway request logs in Neural Inverse Govern, read and search them, open sealed bodies, and attribute traffic with metadata, tags and client identity.

Every gateway request is in the audit log as models.gateway.request, without prompt content. Request logs add a searchable row per request and, if you choose, the bodies, sealed under your organisation's key.

Turn request logs on

Request logs are off by default. Open Models > Request log settings, or:

curl -sS -X PUT "$KEYSTONE_URL/api/v1/models/logging" \
  -H "Authorization: Bearer $ADMIN_TOKEN" -H 'Content-Type: application/json' \
  -d '{"mode": "metadata", "retention_days": 30, "max_classification": "internal"}'
FieldValues
modeoff, metadata (one row per request) or full (metadata plus bodies)
retention_days1 to 365
max_classificationThe strictest classification whose bodies full keeps (default internal)

Every field is required. Reading the settings needs models:view; changing them needs models:admin and is audited as models.logging.put. full needs the deployment's key management service (503 models.request_logs.unavailable otherwise).

What a row holds

One row per request, rewritten by each upstream attempt and ending with the outcome the caller got. Refusals are logged too, including those refused before the caller was resolved.

Fields include request_id, api, requested_model, route, model_key, status (completed, upstream_error, client_closed or refused), http_status, refusal_code, attempts, input_tokens, output_tokens, cost_micros, latency_ms, cache, stream, user_id or api_key_id, project_id, classification, prompt, context_request_id, client_id, client_app, has_bodies and body_note.

Bodies

In full mode the row also keeps the request as sent upstream after DLP (the redacted body, never the original) and the answer as the caller received it, each at most 2 MiB. Each body is sealed with AES-256-GCM under a data key wrapped by the organisation's key models-gateway-logs. Nothing is stored unsealed.

Bodies are never kept for a request in a regulated project, whatever max_classification says. When a body is not kept, body_note says why: classification, too_large, unavailable, seal_failed or not_scanned.

Read logs

Open Models > Request logs (under Monitor) or AI Gateway > Gateway requests.

RoutePermissionAudit
GET /api/v1/models/logsmodels:viewmodels.request_log.list
GET /api/v1/models/logs/{request_id}models:viewmodels.request_log.get
GET /api/v1/models/logs/{request_id}?include=bodiesmodels:adminmodels.request_log.read_bodies, committed with the read

GET /logs filters by from, to, user_id, model (answering model, requested model or route), status and context_request_id, pages with limit (1 to 200) and cursor, and returns newest first.

Rows older than the retention are deleted hourly by models.request_log_purge (schedule NI_AUTH_MODELS_REQUEST_LOG_PURGE_SCHEDULE, off disables it).

Attribute traffic

Request headerRule
X-Keystone-MetadataOne JSON object, at most 8192 bytes and 16 keys. Keys match ^[a-z][a-z0-9_.-]{0,63}$; values are strings of at most 256 bytes. Keys starting with keystone. are reserved.
X-Keystone-TagsUp to 10 comma-separated tags matching ^[A-Za-z0-9][A-Za-z0-9_.:/@-]{0,63}$
X-Keystone-Clientname/version of the calling app, recorded as advisory

A header that breaks a rule is refused with 400 invalid_request before anything is reserved. Metadata and tags are DLP-scanned at the request's classification, carried into usage events, the audit record and route conditions, and never sent to the provider. A gateway key's own metadata wins over the header's.

The OAuth client of the caller's token (client_id) is recorded as verified. X-Keystone-Client is recorded as advisory, because a client can send anything.

Token counting

POST /api/v1/models/gateway/v1/messages/count_tokens counts a request's input tokens. It is decided like a real request (access, DLP, guardrails, rate limits) and audited with operation: count_tokens. Models served through the Anthropic wire format are counted by their provider with the organisation's key; any other model, or a failed provider count, is answered with the gateway's estimate and "estimated": true. Nothing is generated and no budget is reserved.

Other views

Console pageShows
Models > Provider healthProbe results and circuit state per connection
Models > Model usageUsage and spend from the gateway's usage events
AI Gateway > Gateway overview, Gateway costsTraffic and FinOps views
AI Gateway > Gateway keys > key > UsagePer-key analytics

The organisation's model usage also appears in Insights. Request logs and usage events are separate from the audit log, which is described on Audit log.

Last reviewed 17 October 2026View as Markdown

Request logs and observability · Docs · Neural Inverse