Skip to main content
Visibility is the foundation of Zero-Trust. ThornGuard writes an asynchronous audit log for every significant action processed through the proxy. These logs are stored in a highly durable, globally distributed Cloudflare D1 (SQLite) database.

Database Schema

Every event is recorded in the audit_logs table with the following schema:
ColumnTypeDescription
idINTEGERInternal primary key (auto-incrementing).
log_idTEXTPublic-facing UUID identifier (crypto.randomUUID()). Used by the dashboard.
trace_idTEXTCorrelation ID shared with client-visible x-thornguard-trace-id headers.
timestampDATETIMEUTC timestamp (defaults to CURRENT_TIMESTAMP).
license_hashTEXTA SHA-256 hash of the x-thornguard-license used to authenticate the request.
target_urlTEXTThe upstream server requested (e.g., api.githubcopilot.com).
rpc_methodTEXTThe specific MCP tool being called (e.g., get_issue).
actionTEXTThe categorization of the event (see Action Types below).
detailsTEXTExtended context, errors, or reasons for blocking.
details_jsonTEXTStructured JSON metadata for richer event context.
policy_rule_idTEXTThe matched policy rule identifier when a policy event is involved.
response_time_msINTEGERTime in milliseconds from request receipt to response completion.
client_ipTEXTClient IP address (captured from CF-Connecting-IP header).
The id field is the internal auto-incrementing primary key. The log_id UUID is the public-facing identifier used by the dashboard and API. Older rows may not have a log_id — the dashboard falls back to id in those cases.

Action Types

Every audit log entry is classified with one of the following action values:
ActionDescription
PROXY_SUCCESSRequest was successfully scrubbed and proxied to upstream.
SSE_STREAM_ESTABLISHEDAn SSE stream was successfully opened to the client.
BLOCKED_MALICIOUSDestructive command intercepted (e.g., rm -rf, sudo).
BLOCKED_AUTHAuthentication failure — license invalid, missing, or expired.
BLOCKED_INSECURE_TARGETTarget URL was rejected because it was not HTTPS.
BLOCKED_ORIGINRequest origin was rejected by the configured allowlist.
BLOCKED_SSRFSSRF attempt blocked — target URL or resolved DNS address was restricted.
BLOCKED_RATE_LIMITRequest dropped because the per-license rate limit was exceeded.
BLOCKED_IP_WHITELISTClient IP was not in the enterprise IP whitelist.
BLOCKED_CUSTOM_DOMAINTarget domain matched a per-license custom blocklist entry.
BLOCKED_CUSTOM_COMMANDCommand pattern matched a per-license custom command blocklist.
BLOCKED_POLICYA structured tenant policy rule blocked the request.
POLICY_AUDITA structured tenant policy rule matched in audit mode.
BLOCKED_APPROVALA tool call was halted pending explicit approval.
PII_REDACTEDPII or secrets were detected and scrubbed from request or response. Details include the types found (e.g., EMAIL, AWS_KEY).
CUSTOM_REDACTION_AUDITA custom enterprise redaction rule matched in audit mode.
UPSTREAM_ERRORThe upstream MCP server returned an error (timeout, non-JSON response, etc.).
AUDIT_PURGELogs were purged via a GDPR deletion request.
PII_REDACTED counts as a threat in the dashboard metrics — it increments the Threats Blocked counter and can appear in the Recent Blocked Threat card.

Querying Logs

Correlation Headers

Successful proxied responses and ThornGuard-generated error responses include:
  • x-thornguard-log-id
  • x-thornguard-trace-id
These values map directly to audit_logs.log_id and audit_logs.trace_id, making it easy to correlate user-visible failures with backend logs and webhook deliveries.

Via the Dashboard

The ThornGuard Dashboard provides a graphical interface for browsing audit logs with filtering by action type, date range, and search — plus 10-second auto-polling for real-time updates. See Dashboard for details.

Via the Wrangler CLI

You can also query logs directly using the Wrangler CLI. View the 10 most recent events:
npx wrangler d1 execute thornguard-audit --remote \
  --command="SELECT log_id, timestamp, action, rpc_method, client_ip, details FROM audit_logs ORDER BY id DESC LIMIT 10;"
View all blocked malicious attempts:
npx wrangler d1 execute thornguard-audit --remote \
  --command="SELECT log_id, timestamp, target_url, details FROM audit_logs WHERE action = 'BLOCKED_MALICIOUS' ORDER BY id DESC;"
View PII redaction events:
npx wrangler d1 execute thornguard-audit --remote \
  --command="SELECT log_id, timestamp, rpc_method, details FROM audit_logs WHERE action = 'PII_REDACTED' ORDER BY id DESC LIMIT 20;"

Log Retention

ThornGuard supports configurable log retention periods per license tier.
  • Default retention: 90 days (Individual), 365 days (Enterprise).
  • Cleanup schedule: A daily cron job runs at 3:00 AM UTC to delete expired logs.
  • Custom retention: Current dashboard controls allow retention changes within your allowed tier limits.

Data Export

Audit logs can be exported for compliance, reporting, or analysis:
  • CSV Export: Download your audit logs as a CSV file from the dashboard Settings page.
  • JSON Export: Available via the ThornGuard API for programmatic access.

GDPR Compliance

ThornGuard supports right-to-deletion requests through a one-click audit log purge:
  • Accessible from the dashboard Settings page under Danger Zone.
  • Purging deletes all audit logs associated with your license.
  • A final AUDIT_PURGE action is logged to maintain a record of the deletion event itself.
Purging audit logs is irreversible. All historical data for your license will be permanently deleted.