Skip to content

Audit Logging

The gateway writes a structured JSON line for every request. Use it for compliance, debugging, and security analysis.

Enable audit logging
qql-go serve
--audit
--audit-file audit.jsonl # omit to write to stderr

Each request produces one JSON line:

Successful request:

{
"ts": "2026-06-18T10:00:00Z",
"subject": "usr_alice",
"email": "alice@example.com",
"tenant_id": "acme-corp",
"roles": ["reader"],
"operation": "EXEC",
"collection": "docs",
"query": "QUERY 'company' FROM docs LIMIT 5",
"status": "ok",
"latency_ms": 12,
"allowed": true
}

Denied request:

{
"ts": "2026-06-18T10:00:01Z",
"subject": "usr_bob",
"operation": "EXEC",
"status": "denied",
"denied": "true",
"denied_reason": "operation DELETE not permitted for current token",
"latency_ms": 1
}
FieldDescription
tsISO 8601 timestamp
subjectJWT sub claim
emailJWT email claim (if present)
tenant_idExtracted tenant claim
rolesExtracted role claim(s)
operationRPC type (EXEC, EXEC_BATCH, EXPLAIN, HEALTH, CONVERT)
collectionTarget collection name
queryThe QQL query string (as received)
statusok or denied
latency_msEnd-to-end request latency in milliseconds
allowedtrue if the request passed policy
denied"true" if the request was denied
denied_reasonHuman-readable denial reason

Audit logging uses a context-passing pattern:

  1. The interceptor creates an empty AuditMeta in the request context.
  2. The handler fills it with AST details (collection name, operation type, query text).
  3. After execution, the interceptor builds the final JSON entry and writes it.

Since each line is JSON, you can query with jq:

Query audit logs with jq
All denied requestsSection titled “All denied requests”
jq 'select(.status == "denied")' audit.jsonl
Requests by tenantSection titled “Requests by tenant”
jq 'select(.tenant_id == "acme-corp")' audit.jsonl
Slow queries (> 100ms)Section titled “Slow queries (> 100ms)”
jq 'select(.latency_ms > 100)' audit.jsonl
All DROP operationsSection titled “All DROP operations”
jq 'select(.query | startswith("DROP"))' audit.jsonl