Skip to main content

Audit Logs

The audit_log table records every significant skill execution. With 259,547+ entries in production, it provides a comprehensive audit trail for debugging, security review, and usage analysis.

Schema

CREATE TABLE audit_log (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
skill_name VARCHAR(255) NOT NULL,
input_summary TEXT, -- Arguments (secrets redacted)
output_summary TEXT, -- Result (secrets redacted)
capability_level VARCHAR(20), -- safe, monitored, controlled, restricted, privileged
risk_level VARCHAR(20), -- low, medium, high (RESTRICTED+ only)
duration_ms INTEGER, -- Execution time in milliseconds
chat_id VARCHAR(255), -- Who triggered it
success BOOLEAN, -- Whether execution succeeded
created_at TIMESTAMPTZ DEFAULT NOW()
);

What Gets Logged

Capability LevelLogged?Notes
SAFENocalculate, datetime — no side effects
MONITOREDNoweb_search, fetch_url — read-only
CONTROLLEDYesgmail, reminders, task_manager
RESTRICTEDYesshell, python_exec, http_request
PRIVILEGEDYesbroker commands

Secret Redaction

All input and output summaries are passed through redact() before writing:

from src.utils.redaction import redact

audit_entry.input_summary = redact(json.dumps(call.arguments))
audit_entry.output_summary = redact(result.output or "")

Redacted Patterns

PatternExample
OpenAI keyssk-[a-zA-Z0-9]{20,}
Anthropic keyssk-ant-[a-zA-Z0-9-]{20,}
Google keysAIza[a-zA-Z0-9-_]{35}
xAI keysxai-[a-zA-Z0-9]{20,}
HuggingFace tokenshf_[a-zA-Z0-9]{20,}
AWS access keysAKIA[A-Z0-9]{16}
Stripe live keyssk_live_[a-zA-Z0-9]{24}
Slack tokensxox[bpoa]-[a-zA-Z0-9-]+
SendGrid keysSG\.[a-zA-Z0-9]{22}\.[a-zA-Z0-9]{43}
Bearer tokensBearer [a-zA-Z0-9+/=]{20,}
Password patternspassword[=:]\S+

Matched patterns are replaced with [REDACTED].

Common Queries

Recent Activity

docker exec agent-postgres psql -U agent -d agent -c "
SELECT skill_name, capability_level, duration_ms, success, created_at
FROM audit_log
ORDER BY created_at DESC
LIMIT 20;
"

Skill Usage Statistics (Last 24h)

docker exec agent-postgres psql -U agent -d agent -c "
SELECT
skill_name,
COUNT(*) as total_calls,
SUM(CASE WHEN success THEN 1 ELSE 0 END) as successes,
ROUND(AVG(duration_ms)) as avg_ms,
ROUND(100.0 * SUM(CASE WHEN success THEN 1 ELSE 0 END) / COUNT(*), 1) as success_rate
FROM audit_log
WHERE created_at > NOW() - INTERVAL '24 hours'
GROUP BY skill_name
ORDER BY total_calls DESC;
"

Error Analysis

docker exec agent-postgres psql -U agent -d agent -c "
SELECT skill_name, output_summary, created_at
FROM audit_log
WHERE success = false
AND created_at > NOW() - INTERVAL '7 days'
ORDER BY created_at DESC
LIMIT 30;
"

High-Risk Skill Calls

docker exec agent-postgres psql -U agent -d agent -c "
SELECT skill_name, input_summary, output_summary, created_at
FROM audit_log
WHERE capability_level IN ('restricted', 'privileged')
ORDER BY created_at DESC
LIMIT 20;
"

Per-User Activity

docker exec agent-postgres psql -U agent -d agent -c "
SELECT chat_id, COUNT(*) as calls, MAX(created_at) as last_active
FROM audit_log
WHERE created_at > NOW() - INTERVAL '7 days'
GROUP BY chat_id
ORDER BY calls DESC;
"

Audit Log Size

The audit log grows at approximately 1 MB per day under normal usage. At 259,547 entries:

  • Size: ~50 MB
  • Index on created_at recommended for large tables

Cleanup

# Delete entries older than 90 days
docker exec agent-postgres psql -U agent -d agent -c "
DELETE FROM audit_log
WHERE created_at < NOW() - INTERVAL '90 days';
"

# Vacuum to reclaim space
docker exec agent-postgres psql -U agent -d agent -c "VACUUM audit_log;"

Real-time Audit Streaming

To watch audit events in real-time:

# Poll every 5 seconds
watch -n5 'docker exec agent-postgres psql -U agent -d agent -c "
SELECT skill_name, capability_level, success, created_at
FROM audit_log
ORDER BY created_at DESC
LIMIT 5;
"'