Skip to content

Audit Logging ​

Wave can log all tool calls and file operations during pipeline execution, producing structured audit trails for compliance, debugging, and monitoring.

Enabling Audit Logging ​

yaml
# In wave.yaml
runtime:
  audit:
    log_dir: .agents/traces/           # Output directory
    log_all_tool_calls: true           # Log every tool invocation
    log_all_file_operations: true      # Log every file read/write/delete

Audit Log Format ​

Audit logs are written as NDJSON files, one per pipeline execution:

.agents/traces/
├── a1b2c3d4-impl-speckit-2026-02-01T10:00:00.ndjson
├── e5f6a7b8-bug-fix-2026-01-30T14:30:00.ndjson
└── ...

Log Entry Schema ​

json
{
  "timestamp": "2026-02-01T10:01:15.234Z",
  "pipeline_id": "a1b2c3d4",
  "step_id": "implement",
  "persona": "craftsman",
  "type": "tool_call",
  "tool": "Write",
  "args": {
    "path": "src/models/user.go"
  },
  "result": "success",
  "duration_ms": 12
}

Entry Types ​

TypeDescriptionRequires
tool_callAny tool invocation (Read, Write, Bash, etc.)log_all_tool_calls: true
file_readFile read operationlog_all_file_operations: true
file_writeFile write or editlog_all_file_operations: true
file_deleteFile deletionlog_all_file_operations: true
permission_deniedBlocked tool callAlways logged
hook_executedPre/post hook executionAlways logged
contract_validationContract check resultAlways logged

Credential Scrubbing ​

Audit logs never capture credential values. Wave automatically redacts environment variables matching these patterns:

  • *_KEY → [REDACTED]
  • *_TOKEN → [REDACTED]
  • *_SECRET → [REDACTED]
  • *_PASSWORD → [REDACTED]
  • *_CREDENTIAL* → [REDACTED]

Example:

json
{
  "type": "tool_call",
  "tool": "Bash",
  "args": {
    "command": "curl -H 'Authorization: Bearer [REDACTED]' https://api.example.com"
  }
}

Querying Audit Logs ​

Find All Writes by a Persona ​

bash
cat .agents/traces/a1b2c3d4-*.ndjson \
  | jq 'select(.persona == "craftsman" and .type == "file_write")'

Find Permission Denials ​

bash
cat .agents/traces/a1b2c3d4-*.ndjson \
  | jq 'select(.type == "permission_denied")'

Summarize Tool Usage ​

bash
cat .agents/traces/a1b2c3d4-*.ndjson \
  | jq -r 'select(.type == "tool_call") | .tool' \
  | sort | uniq -c | sort -rn

Get Timeline of a Step ​

bash
cat .agents/traces/a1b2c3d4-*.ndjson \
  | jq 'select(.step_id == "implement") | {time: .timestamp, type: .type, tool: .tool}'

Audit Logging Levels ​

ConfigurationWhat's LoggedUse Case
Both falseOnly security events (denials, hooks, contracts)Production, low overhead
log_all_tool_calls: trueAll tool invocations + security eventsDebugging, compliance
Both trueEverything — full file-level audit trailSecurity audits, forensics

Performance Impact ​

Audit logging adds minimal overhead:

  • Logs are written asynchronously to disk.
  • NDJSON format is append-only (no parsing or rewriting).
  • File I/O is buffered.

For long-running pipelines, audit log files can grow large. Monitor disk usage in .agents/traces/.

CI/CD Integration ​

yaml
# GitHub Actions: upload audit logs as artifacts
- name: Run Wave pipeline
  run: wave run flow "deploy"
  env:
    ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}

- name: Upload audit logs
  uses: actions/upload-artifact@v4
  if: always()
  with:
    name: wave-audit-logs
    path: .agents/traces/

Further Reading ​

Released under the MIT License.