hoangsonww / hoangsonww/Claude-Code-Agent-Monitor
[Feature]: Tool Risk Audit - reviewable security lens over executed commands, file writes, and network calls
- Dominant language
- TypeScript
- Stars
- 1k
- Forks
- 234
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 18
Description
### What problem does this solve?
The dashboard already ingests every `PreToolUse` / `PostToolUse` payload, which means the full text of every `Bash` command, every `Write`/`Edit` target path, and every `WebFetch` URL an agent ran is sitting in the `events` table. But there is no way to *review* that as a security surface.
Today, answering "what did my agents actually execute on this machine last week?" means paging through the Activity Feed one event at a time, or filtering to `tool_name = Bash` and reading a few hundred rows by hand. In practice nobody does this, which is exactly the problem: agents run with `--dangerously-skip-permissions` or bypass mode more often than anyone likes to admit, and the record of what they did is write-only.
Concretely, there is no way to ask:
- Which sessions ran a `sudo`, an `rm -rf`, or a `curl … | sh`?
- Did anything write outside the project root — into `~/.ssh`, `~/.aws`, `~/.claude/settings.json`, or a system path?
- Which external hosts were fetched, and by which agent?
- Did any tool call touch a file matching `*.env`, `*credentials*`, `id_rsa`, or a `.pem`?
### Proposed solution
A dedicated **Tool Risk Audit** view — a curated security lens over data the dashboard already stores, not a new collector.
**Server** — a new `server/lib/tool-risk.js` that classifies a tool event into zero or more risk signals using a declarative, user-visible ruleset. First-cut signal families:
| Signal | Matches |
| --- | --- |
| `privilege` | `sudo`, `doas`, `chmod 777`, `chown root` |
| `destructive` | `rm -rf`, `git reset --hard`, `git push --force`, `DROP TABLE`, `truncate` |
| `remote-exec` | `curl`/`wget` piped into a shell, `npx` of an unpinned remote package |
| `credential-access` | reads/writes matching `.env`, `id_rsa`, `*.pem`, `credentials`, `.aws/`, `.ssh/` |
| `egress` | `WebFetch`/`WebSearch` targets, plus network-capable Bash commands, grouped by host |
| `outside-cwd` | `Write`/`Edit` whose resolved path escapes the session's `cwd` |
Each signal carries a severity and the exact substring that triggered it, so the UI can highlight *why* a row was flagged rather than showing an opaque score.
`GET /api/audit/tools` returns the flagged events with the usual filter set (session, project, date range, signal, severity, provider) and supports the same pagination shape as `/api/events`. `GET /api/audit/summary` returns counts per signal and per project for the header tiles.
**UI** — an Audit page: severity tiles across the top, a filterable table below (time, session, agent, tool, matched signal, the command/path itself), and click-through into the existing `EventDetail` for the full payload. Export to CSV/JSON so the output can go into a real review.
**Configuration** — the ruleset ships as data, and Settings gets an editor for it: add a pattern, mute a signal, or allowlist a path prefix (e.g. "my dotfiles repo legitimately writes to `~/.ssh/config`"). Muting is per-pattern and recorded, not a global off switch.
**CLI** — `ccam audit --since 7d --severity high` prints the same view for headless machines, which is where this matters most.
### Alternatives considered
- **Do it with the Advanced Query Explorer (#10).** That gives you the *ability* to write the query; it doesn't give you the ruleset, the severities, or a review workflow. A generic query builder and a curated security lens solve different problems — the audit view could be built on top of the explorer's query layer if that lands first.
- **Block risky commands at the hook.** Out of scope and arguably wrong for this project: the hooks are documented as fail-safe and non-blocking, and turning the monitor into an enforcement point changes its risk profile entirely. This proposal is strictly read-only.
- **Regex-grep the transcripts offline.** Works once, doesn't compose with sessions/agents/projects, and misses everything the transcript doesn't include.
### Area
Sessions / Agents
### How important is this to you?
Would significantly improve my workflow
### Additional context
Complements #148 (privacy controls for hook payload ingestion) rather than fighting it: if a user redacts payloads, the audit view degrades gracefully to the signals still derivable from `tool_name` and `summary`, and should say so in the UI instead of silently showing an empty, falsely-reassuring table.
Contributor guide
Assessment
This issue has not been assessed yet.