CLI agent session log analyzer — parse, audit, and enforce security policies on AI coding agent sessions (Claude Code, Codex, Gemini CLI, and more).
AI coding agents run commands, read files, and make network requests on your behalf. Most of the time that's great. Sometimes it's not. An agent might:
- Run
rm -rf /orgit push --force(destructive commands) - Read your
.envfiles orcredentials.json(secret exposure) - Upload data to
webhook.siteorngrok.io(data exfiltration) - Execute
sudocommands (privilege escalation) - Leak API keys, JWTs, or private keys in outputs (sensitive data)
sessaudit scans agent session logs against configurable security policies, detects violations, scores risk, and generates compliance reports. Drop it into your CI/CD pipeline to catch dangerous agent behavior before it reaches production.
- Multi-format parser — Claude Code
action_log.jsonl, generic JSON agent logs, arrays, wrapped objects, JSONL - YAML policy engine — Define rules as YAML with regex patterns, file globs, domain lists, resource limits
- 10 built-in rules — Destructive commands, secret access, sensitive data, network exfiltration, privilege escalation, resource limits
- Risk scoring (0-100) — Configurable weights per severity, category caps, pass/fail threshold
- 3 output formats — JSON (CI/CD), colored text (human), table (overview)
- Session replay — Chronological timeline with inline violation highlights
- Severity filtering — Show only critical, high, or above
- Context-aware — Shows surrounding actions for each violation
# Install globally
npm install -g sessaudit
# Or use directly
npx sessaudit scan ./session-logs/# Scan a session log with default policies
sessaudit scan ./action_log.jsonl
# Scan with JSON output for CI/CD
sessaudit scan ./logs/ --format json
# Create a custom policy
sessaudit policy init --output my-policy.yaml
# Scan with custom policy
sessaudit scan ./logs/ --policy my-policy.yaml
# Replay a session timeline
sessaudit replay ./action_log.jsonl
# Generate a compliance report
sessaudit report ./logs/ --format table --output report.txtScan agent session logs for policy violations.
sessaudit scan <path> [options]
Options:
-p, --policy <path> Path to policy YAML file (default: built-in policy)
-f, --format <format> Output format: json, text, table (default: text)
-s, --severity <level> Minimum severity filter: critical, high, medium, low, info
-t, --threshold <number> Risk score threshold 0-100 (default: 70)
--context <lines> Context lines around violations (default: 2)
--parser <format> Parser format: auto, claude_code, generic_json (default: auto)Exit codes:
0— All sessions passed1— One or more sessions failed (violations above threshold)2— Error (bad arguments, file not found, etc.)
Create a default policy file with all built-in rules.
sessaudit policy init [options]
Options:
-o, --output <path> Output path (default: sessaudit-policy.yaml)Validate a policy YAML file for correctness.
sessaudit policy validate <path>Checks for:
- Valid YAML syntax
- Correct severity/category values
- Regex pattern compilation
- Duplicate rule IDs
- Required config fields
Generate a compliance report from session logs.
sessaudit report <path> [options]
Options:
-p, --policy <path> Path to policy YAML file
-f, --format <format> Output format: json, text, table (default: text)
-s, --severity <level> Minimum severity filter
-t, --threshold <number> Risk score threshold (default: 70)
-o, --output <path> Write report to file instead of stdout
--parser <format> Parser format: auto, claude_code, generic_jsonReplay a session timeline with violation highlights.
sessaudit replay <path> [options]
Options:
-p, --policy <path> Path to policy YAML file
--parser <format> Parser format: auto, claude_code, generic_jsonPolicies are YAML files with named rules. Each rule specifies a severity, category, and detection config.
name: my-policy
version: 1.0.0
description: Custom security policy
rules:
- id: block-force-push
name: Block Force Push
description: Prevent git force push
severity: critical
category: command
enabled: true
config:
type: command_blocklist
patterns:
- "git\\s+push\\s+--force"
- "git\\s+push\\s+-f\\b"
regex: trueBlock commands matching patterns (regex or substring).
config:
type: command_blocklist
patterns:
- "rm\\s+-rf\\s+/"
- "DROP\\s+TABLE"
regex: true # false for substring matchingBlock access to sensitive files.
config:
type: file_access
blocked_patterns:
- ".env"
- ".env.*"
- "*.pem"
- "credentials.json"
operations:
- read
- writeControl network access by domain.
config:
type: network_access
allowed_domains: [] # empty = no allowlist enforcement
denied_domains:
- webhook.site
- ngrok.io
- requestbin.comLimit resource usage per session.
config:
type: resource_limit
resource: file_writes # file_writes, file_reads, commands, total_actions
max_count: 100Detect sensitive data patterns in inputs/outputs.
config:
type: sensitive_data
patterns:
- "AKIA[0-9A-Z]{16}" # AWS access keys
- "-----BEGIN\\s+PRIVATE\\s+KEY-----"
scan:
- input
- outputMatch any regex against action fields.
config:
type: custom_regex
pattern: "eval\\s*\\("
scan:
- input
- output
- tool| Level | Weight | Description |
|---|---|---|
critical |
25 | Immediate security risk, data loss possible |
high |
15 | Significant security concern |
medium |
8 | Moderate risk, policy deviation |
low |
3 | Minor concern, informational |
info |
1 | Audit trail, no action needed |
command— Dangerous command executionfile_access— Unauthorized file accessnetwork— Network access violationsresource— Resource limit exceededsensitive_data— Sensitive data exposureprivilege— Privilege escalationcustom— User-defined rules
sessaudit ships with 10 rules covering common threats:
| ID | Name | Severity | Category |
|---|---|---|---|
cmd-destructive |
Destructive Command Detection | critical | command |
cmd-git-dangerous |
Dangerous Git Operations | high | command |
file-secrets |
Secret/Credential File Access | critical | file_access |
data-sensitive-output |
Sensitive Data in Output | high | sensitive_data |
net-exfiltration |
Network Exfiltration Patterns | high | network |
res-file-writes |
Excessive File Modifications | medium | resource |
res-commands |
Excessive Command Execution | low | resource |
priv-escalation |
Privilege Escalation Patterns | critical | privilege |
cmd-curl-upload |
Data Upload via curl/wget | medium | command |
data-env-exposure |
Environment Variable Exposure | medium | sensitive_data |
Each session gets a risk score from 0 (dangerous) to 100 (safe):
- Start at 100 (base score)
- For each violation, deduct based on severity weight
- Cap deduction per category at 50 (prevents single category from zeroing the score)
- Floor at 0, ceiling at 100
Default threshold: 70 (sessions scoring below fail)
Configure scoring via the API:
import { scanSession, getBuiltinPolicy } from 'sessaudit';
const result = scanSession(session, getBuiltinPolicy(), {
baseScore: 100,
weights: { critical: 25, high: 15, medium: 8, low: 3, info: 1 },
maxCategoryDeduction: 50,
threshold: 80, // stricter threshold
});{"timestamp":"2026-04-09T10:00:00Z","tool":"Bash","input":"npm test","output":"passed"}
{"timestamp":"2026-04-09T10:00:05Z","tool":"Read","input":"/project/src/index.ts","output":"..."}
{"timestamp":"2026-04-09T10:00:10Z","tool":"Write","input":"/project/src/fix.ts","output":"written"}{
"session_id": "session-001",
"agent": "codex",
"start_time": "2026-04-09T09:00:00Z",
"end_time": "2026-04-09T09:30:00Z",
"actions": [
{
"timestamp": "2026-04-09T09:00:00Z",
"type": "command",
"tool": "shell",
"input": "ls -la",
"output": "total 42"
}
]
}Also supports: arrays of entries, entries/events/logs wrapper keys, time/date timestamp aliases, args input alias, command/name tool aliases.
import {
parseSessionFile,
getBuiltinPolicy,
scanSessions,
generateReport,
formatReport,
replaySession,
formatReplay,
} from 'sessaudit';
// Parse session logs
const sessions = parseSessionFile('./logs/');
// Load policy (built-in or custom)
const policy = getBuiltinPolicy();
// Scan all sessions
const results = scanSessions(sessions, policy);
// Generate and format report
const report = generateReport(results, policy.name, {
riskThreshold: 70,
severityFilter: null,
format: 'json',
});
const output = formatReport(report, 'json');
console.log(output);
// Replay a session
const replay = replaySession(sessions[0], results[0].violations);
console.log(formatReplay(replay));- name: Audit agent sessions
run: |
npx sessaudit scan ./agent-logs/ \
--format json \
--threshold 80 \
--severity medium \
--output audit-report.json# In CI scripts
sessaudit scan ./logs/ --format json > report.json
if [ $? -eq 1 ]; then
echo "Agent session audit FAILED"
exit 1
fi======================================================================
sessaudit — Agent Session Security Report
======================================================================
Policy: sessaudit-default
Sessions: 3
----------------------------------------------------------------------
SUMMARY
----------------------------------------------------------------------
Total Violations: 7
Average Score: 45/100
Pass Rate: 33% (1/3)
Violations by Severity:
[CRIT] 3
[HIGH] 2
[MED] 2
{
"timestamp": "2026-04-09T10:00:00Z",
"policy": "sessaudit-default",
"summary": {
"totalSessions": 3,
"totalViolations": 7,
"passedSessions": 1,
"failedSessions": 2,
"averageRiskScore": 45
},
"sessions": [...]
}sessaudit/
src/
cli/ CLI entry point and subcommands
parser/ Session log parsers (JSONL, JSON)
policy/ Policy engine and built-in rules
scanner/ Violation detection engine
reporter/ Report generators (JSON, text, table)
replay/ Session timeline replay
scoring/ Risk scoring engine
types/ TypeScript interfaces
index.ts Public API exports
tests/
unit/ Unit tests (parser, policy, scanner, scoring, reporter, replay)
integration/ End-to-end CLI and API tests
fixtures/ Sample session logs and policies
policies/ Built-in default policy YAML
# Install dependencies
npm install
# Build
npm run build
# Run tests
npm test
# Type check
npm run lintMIT