# 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 <id>   ← filter by plan
           ├── agents audit list --type <type> ← filter by event
           ├── agents audit list --project <p> ← filter by project
           ├── agents audit list --since <ts>  ← filter by time
           ├── agents audit show <id>  ← inspect one entry
           ├── agents audit count      ← total count
           └── agents audit prune --days <n>   ← 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 <ID>` 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 <ID>` 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
