# Audit Log & Security: Tracking Every Security-Relevant Operation ## Overview CleverAgents maintains a tamper-evident **audit log** that records every security-relevant operation: plan applies, cancellations, resource modifications, configuration changes, session creations, and more. The `agents audit` command group gives you full visibility into this log — list entries with powerful filters, inspect individual events in detail, and prune old records to manage storage. This example walks through the complete audit workflow: from viewing an empty log to populating it with real events, filtering by plan/project/type/time, drilling into individual entries, and pruning stale records with or without interactive confirmation. ## Prerequisites - CleverAgents installed (`pip install cleveragents`) - Python 3.12 or higher ## What You'll Learn - How to list audit log entries with `agents audit list` - How to filter entries by plan ID, project, event type, and timestamp - How to inspect a single entry in full detail with `agents audit show` - How to count total entries with `agents audit count` - How to prune old entries with `agents audit prune` (with and without interactive confirmation) - The nine security event types CleverAgents tracks - How the async write-behind queue ensures audit recording never blocks your agent operations --- ## The Audit Log at a Glance ``` Security-relevant operation occurs │ ▼ AuditService.record(event_type=..., plan_id=..., details=...) │ ▼ (async write-behind, non-blocking) SQLite audit_log table │ ├── agents audit list ← browse all entries ├── agents audit list --plan ← filter by plan ├── agents audit list --type ← filter by event ├── agents audit list --project

← filter by project ├── agents audit list --since ← filter by time ├── agents audit show ← inspect one entry ├── agents audit count ← total count └── agents audit prune --days ← retention cleanup ``` ### Tracked Event Types | Event Type | When It's Recorded | |---|---| | `plan_applied` | An AI plan's changes were written to disk | | `plan_cancelled` | A running plan was cancelled | | `resource_modified` | A resource was changed by an agent tool | | `correction_applied` | An auto-correction was applied to a plan | | `config_changed` | Application configuration was modified | | `entity_deleted` | A plan, resource, or other entity was deleted | | `session_created` | A new agent session was started | | `auth_success` | A successful authentication event | | `auth_failure` | A failed authentication attempt | --- ## Step-by-Step Walkthrough ### Step 1: Check the Audit Log (Empty State) When no operations have been recorded yet, `agents audit list` gives a clear empty-state message: ``` $ agents audit list No audit entries found. ``` Exit code: `0` --- ### Step 2: View All Audit Entries After your agents have been running, the audit log fills up with events. Here is what a typical log looks like after a session with multiple operations: ``` $ agents audit list Audit Log (5 entries) #5 session_created project=my-webapp 2026-04-07T14:43:40.736608 #4 plan_cancelled plan=plan-xyz789 project=data-pipeline 2026-04-07T14:43:40.735990 #3 resource_modified plan=plan-abc123 project=my-webapp 2026-04-07T14:43:40.735366 #2 config_changed project=my-webapp 2026-04-07T14:43:40.734501 #1 plan_applied plan=plan-abc123 project=my-webapp 2026-04-07T14:43:40.730826 ``` Exit code: `0` > **Note:** Entries are displayed **newest first** — the most recent event > appears at the top. Each line shows the entry ID (`#N`), event type, plan > and project context (when available), and the precise ISO-8601 timestamp. --- ### Step 3: Filter by Plan ID To see only the events associated with a specific plan, use `--plan`: ``` $ agents audit list --plan plan-abc123 Audit Log (2 entries) #3 resource_modified plan=plan-abc123 project=my-webapp 2026-04-07T14:43:40.735366 #1 plan_applied plan=plan-abc123 project=my-webapp 2026-04-07T14:43:40.730826 ``` Exit code: `0` This is invaluable for post-incident review: given a plan ID from an alert or error report, you can immediately see every operation that plan performed. --- ### Step 4: Filter by Event Type To focus on a specific category of event, use `--type`: ``` $ agents audit list --type plan_applied Audit Log (1 entries) #1 plan_applied plan=plan-abc123 project=my-webapp 2026-04-07T14:43:40.730826 ``` Exit code: `0` Useful for compliance reporting: "show me every plan that was applied in the last 30 days." --- ### Step 5: Filter by Project To scope the audit log to a single project, use `--project`: ``` $ agents audit list --project data-pipeline Audit Log (1 entries) #4 plan_cancelled plan=plan-xyz789 project=data-pipeline 2026-04-07T14:43:40.735990 ``` Exit code: `0` --- ### Step 6: Limit the Number of Results For large audit logs, use `--limit` (or `-n`) to cap the output: ``` $ agents audit list --limit 3 Audit Log (3 entries) #5 session_created project=my-webapp 2026-04-07T14:43:40.736608 #4 plan_cancelled plan=plan-xyz789 project=data-pipeline 2026-04-07T14:43:40.735990 #3 resource_modified plan=plan-abc123 project=my-webapp 2026-04-07T14:43:40.735366 ``` Exit code: `0` The default limit is 50. Since entries are returned newest-first, `--limit 3` gives you the three most recent events. --- ### Step 7: Filter by Timestamp (--since) To see only events after a specific point in time, use `--since` with an ISO-8601 timestamp: ``` $ agents audit list --since 2026-03-31T14:43:41 Audit Log (2 entries) #3 session_created project=new-project 2026-04-07T14:43:41.011285 #2 config_changed 2026-04-02T14:43:41.010905 ``` Exit code: `0` This is perfect for scheduled compliance reports: "show me everything that happened since the last weekly review." --- ### Step 8: Inspect a Single Entry in Full Detail The `agents audit show ` command displays the complete metadata for one entry, including the full structured `details` payload: ``` $ agents audit show 1 Audit Entry #1 Event type: plan_applied Created at: 2026-04-07T14:43:40.730826 Plan ID: plan-abc123 Project: my-webapp Actor: openai/gpt-4o User: alice@example.com Details: { "files_changed": 3, "validation_passed": true, "duration_ms": 1250 } ``` Exit code: `0` The `details` field is a free-form JSON object — each event type populates it with relevant context. For `plan_applied`, you can see how many files were changed, whether validation passed, and how long the operation took. --- ### Step 9: Inspect a Configuration Change Entry Here is a `config_changed` entry showing the old and new values of a setting: ``` $ agents audit show 2 Audit Entry #2 Event type: config_changed Created at: 2026-04-07T14:43:40.734501 Plan ID: - Project: my-webapp Actor: - User: bob@example.com Details: { "key": "max_tokens", "old_value": 4096, "new_value": 8192 } ``` Exit code: `0` Fields that are not applicable to an event type are shown as `-` (dash). --- ### Step 10: Handle a Non-Existent Entry If you request an entry ID that does not exist, the command exits with code 1: ``` $ agents audit show 99999 Audit entry 99999 not found. ``` Exit code: `1` --- ### Step 11: Count Total Entries For a quick summary without listing all entries: ``` $ agents audit count Total audit log entries: 5 ``` Exit code: `0` --- ### Step 12: Prune Old Entries (Non-Interactive) For automated cleanup in scripts and CI pipelines, use `--yes` to skip the confirmation prompt: ``` $ agents audit prune --days 30 --yes Pruned 5 audit log entries. ``` Exit code: `0` This deleted 5 entries that were older than 30 days, leaving the 2 recent entries intact. --- ### Step 13: Prune with Interactive Confirmation Without `--yes`, the command prompts for confirmation before deleting anything: ``` $ agents audit prune --days 30 Delete audit entries older than 30 days? [y/N]: y Pruned 3 audit log entries. ``` Exit code: `0` If you answer `n`, the operation is safely aborted: ``` $ agents audit prune --days 30 Delete audit entries older than 30 days? [y/N]: n ``` Exit code: `1` (aborted) --- ### Step 14: Prune with Zero Retention (Keep Everything) Setting `--days 0` is a special value meaning "keep everything indefinitely." The command detects this and exits without deleting anything: ``` $ agents audit prune --days 0 Retention is set to 0 (keep everything). Nothing to prune. ``` Exit code: `0` This is also the **default** setting — CleverAgents keeps all audit entries forever unless you explicitly configure a retention period. --- ## Complete Command Reference ``` $ agents audit --help Usage: agents audit [OPTIONS] COMMAND [ARGS]... View and manage the audit log for security-relevant operations. ╭─ Options ────────────────────────────────────────────────────────────────────╮ │ --install-completion Install completion for the current shell. │ │ --show-completion Show completion for the current shell, to copy │ │ it or customize the installation. │ │ --help Show this message and exit. │ ╰──────────────────────────────────────────────────────────────────────────────╯ ╭─ Commands ───────────────────────────────────────────────────────────────────╮ │ list List audit log entries with optional filters. │ │ show Show a single audit entry with full metadata. │ │ prune Delete audit entries older than the retention period. │ │ count Show the total number of audit log entries. │ ╰──────────────────────────────────────────────────────────────────────────────╯ ``` ### `agents audit list` Options ``` $ agents audit list --help Usage: agents audit list [OPTIONS] List audit log entries with optional filters. ╭─ Options ────────────────────────────────────────────────────────────────────╮ │ --plan TEXT Filter by plan ID. │ │ --project TEXT Filter by project name. │ │ --type TEXT Filter by event type. │ │ --since TEXT Only entries after this ISO-8601 timestamp. │ │ --limit -n INTEGER Maximum entries to display. [default: 50] │ │ --help Show this message and exit. │ ╰──────────────────────────────────────────────────────────────────────────────╯ ``` ### `agents audit show` Options ``` $ agents audit show --help Usage: agents audit show [OPTIONS] AUDIT_ID Show a single audit entry with full metadata. ╭─ Arguments ──────────────────────────────────────────────────────────────────╮ │ * audit_id INTEGER The audit entry ID to display. [required] │ ╰──────────────────────────────────────────────────────────────────────────────╯ ╭─ Options ────────────────────────────────────────────────────────────────────╮ │ --help Show this message and exit. │ ╰──────────────────────────────────────────────────────────────────────────────╯ ``` ### `agents audit prune` Options ``` $ agents audit prune --help Usage: agents audit prune [OPTIONS] Delete audit entries older than the retention period. ╭─ Options ────────────────────────────────────────────────────────────────────╮ │ --days INTEGER Delete entries older than this many days. Overrides │ │ config. │ │ --yes -y Skip confirmation prompt. │ │ --help Show this message and exit. │ ╰──────────────────────────────────────────────────────────────────────────────╯ ``` --- ## Key Takeaways 1. **Every security-relevant operation is recorded automatically.** You don't need to instrument your code — CleverAgents records `plan_applied`, `config_changed`, `session_created`, and six other event types whenever they occur. 2. **The audit log is non-blocking.** Entries are written via an async write-behind queue on a background thread, so audit recording never slows down your agent operations. The queue is flushed before the service closes, ensuring no data loss. 3. **Entries are returned newest-first.** `agents audit list` always shows the most recent events at the top, making it easy to see what just happened. 4. **Filters compose naturally.** You can combine `--plan`, `--project`, `--type`, `--since`, and `--limit` in a single command to narrow down exactly the events you care about. 5. **The `details` field is structured JSON.** Each event type populates it with relevant context — file counts, tool names, old/new config values, session IDs, etc. Use `agents audit show ` to see the full payload. 6. **Default retention is "keep everything."** Setting `--days 0` (or leaving `CLEVERAGENTS_AUDIT_RETENTION_DAYS` unset) means the audit log grows indefinitely. Set a retention period for production deployments where storage is a concern. 7. **The `--yes` flag is safe for automation.** Use `agents audit prune --days 90 --yes` in cron jobs or CI pipelines to enforce a rolling retention window without interactive prompts. --- ## Configuration You can configure audit behaviour via environment variables: | Variable | Default | Description | |---|---|---| | `CLEVERAGENTS_AUDIT_RETENTION_DAYS` | `0` | Days to keep entries (0 = forever) | | `CLEVERAGENTS_AUDIT_ASYNC` | `true` | Use async write-behind queue | | `CLEVERAGENTS_AUDIT_QUEUE_MAXSIZE` | `10000` | Max pending entries in queue | Example — enforce a 90-day retention window: ```bash export CLEVERAGENTS_AUDIT_RETENTION_DAYS=90 agents audit prune --yes # Run this in a daily cron job ``` --- ## Try It Yourself ```bash # 1. Check the current state of your audit log agents audit list # 2. Filter to a specific project agents audit list --project my-webapp # 3. See only plan_applied events from the last 7 days agents audit list --type plan_applied --since $(date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%S) # 4. Inspect a specific entry in full detail agents audit show 42 # 5. Count total entries agents audit count # 6. Prune entries older than 90 days (with confirmation) agents audit prune --days 90 # 7. Prune non-interactively (for scripts/cron) agents audit prune --days 90 --yes ``` --- *This example was automatically generated and verified by the CleverAgents UAT system.* *Feature area: Audit log and security commands | Test cycle: 1* --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: uat-tester