Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Action log

The audit log records what CSM found. The action log records what CSM did: one record per action, one file, one schema, whether the action came from the daemon, an operator command or the web UI.

/var/log/csm/actions.jsonl
csm actions                      # recent actions, one line each
csm actions --since 24h          # RFC 3339 timestamp or a duration
csm actions --op respond.block_ip
csm actions --json               # the raw records

Schema

{
  "v": 1,
  "ts": "2026-09-09T10:32:14.512938Z",
  "hostname": "host.example.com",
  "op": "respond.quarantine_file",
  "actor": "daemon",
  "finding_id": "8e3f1c204c1d8b95",
  "target": "/home/alice/public_html/uploads/x.php",
  "account": "alice",
  "reason": "webshell_realtime",
  "before": {"exists": true, "sha256": "5f2b...", "size": 1841, "mode": "-rw-r--r--", "uid": 1001, "gid": 1001},
  "after": {"exists": false},
  "result": "applied",
  "recovery_path": "/opt/csm/quarantine/2026-09-09T10-32-14-x.php"
}
FieldMeaning
opThe privileged operation, using the IDs from the capability matrix. The matrix says what an operation may do; this says what it did.
actionThe specific change within an operation, such as block, unblock, apply or rollback.
actordaemon, cli or webui. actor_detail carries the operator’s source address or the command name.
finding_idThe finding that caused the action, using the same ID the audit log emits, so the two streams join.
commandThe exact argv when CSM ran a program. Absent when the action used system calls only.
before / afterThe target file’s digest, size, mode and owner around the change. "exists": false after a quarantine is the record that the file is gone.
resultapplied, dry_run, failed or refused. A dry-run record says what CSM would have done.
undoA command that reverses the action, when an exact inverse is available.
recovery_pathRetained quarantine content or a pre-clean backup, with a .meta sidecar. Use the quarantine recovery workflow; csm restore accepts state archives, not these files.

Attempted operations include failures and safety refusals. An already blocked address does not produce another applied record. A successful file replacement or quarantine with a later warning stays visible with its recovery path.

A refused action is recorded too. “The safety rules stopped this” and “CSM never looked” are different operational states, and only one of them is a reason to change the configuration.

v is the schema version. It is bumped only on an incompatible change, so a parser can pin on v: 1 and ignore unknown keys.

Long reasons and error messages are truncated with an explicit marker so one action cannot make the history unreadable. Targets and command arguments are preserved.

A file larger than 64 MiB is recorded without a digest rather than stalling the action while it is hashed. Quarantine digests come from the captured copy, after the move. Cleaning digests describe the exact bytes read and installed through the pinned file handles. Directories and symlinks have no digest.

What is covered

The capability matrix has an “Action record” column. Six operations write here today: firewall blocks and unblocks (automatic and operator), whole-ruleset changes, file quarantine, surgical file cleaning, and process termination. Everything else appears in the daemon log only. The column is the authoritative list. Tests exercise the operation paths, including failures and concurrent blocks.

The firewall keeps its own audit file because the web UI and the API read it. Its entries also appear here; dry-run decisions, failed attempts and whole ruleset apply/rollback records are recorded directly on this stream. Startup rollback records are written before the daemon requests a restart.

actor uses the caller’s attribution when available and otherwise identifies the process performing the action. Some web UI requests therefore record as daemon; the web UI’s own action log retains the operator’s source address.

Rotation

The file rotates to actions.jsonl.1 at 10 MB. csm actions reads both. Readers and writers coordinate rotation through actions.jsonl.lock. Readers pin both files before releasing the lock, so rotation cannot hide records and a slow reader does not hold up a writer. CSM handles this rotation itself; the installed logrotate configuration leaves the live file alone and archives actions.jsonl.1, which the sink never writes to again, for 90 days. Older history is compressed there and is not read by csm actions; ship the stream to a SIEM if you need it queryable.

Recording is best effort. Sink errors or panics do not change an action’s outcome. A write waits at most 250 ms, with at most 64 writes outstanding; a stalled sink or saturation can lose records. Normal CLI writes finish before the command exits. Keep this log on a local filesystem and monitor write-error warnings. The stream is not a transactional guarantee that every host change survives a crash.