runok audit
runok audit displays recorded audit log entries. Every exec and hook evaluation is logged automatically (unless disabled), and this subcommand lets you query those entries by time range, action, or command pattern.
runok audit [options]-c, --config <path>
Section titled “-c, --config <path>”See Global Flags. The audit log directory is read from the loaded config’s audit.path.
--action <allow|deny|ask>
Section titled “--action <allow|deny|ask>”Filter entries by the evaluation result.
--since <timespec>
Section titled “--since <timespec>”Show only entries after the given time. Accepts relative durations (30m, 1h, 7d) or absolute timestamps (2026-03-01, 2026-03-01T12:00:00Z).
--until <timespec>
Section titled “--until <timespec>”Show only entries before the given time. Same format as --since.
--command <pattern>
Section titled “--command <pattern>”Filter entries whose command string contains the given substring.
--dir <path>
Section titled “--dir <path>”Filter entries by working directory. Only shows entries executed in the given directory or its subdirectories. The path is resolved to its canonical (absolute, symlink-resolved) form before matching.
--limit <n>
Section titled “--limit <n>”Maximum number of entries to display.
Default: 50
--json
Section titled “--json”Output entries as JSON (one object per line). Useful for piping into jq or other tools.
Examples
Section titled “Examples”Show the last 50 audit log entries (default):
runok auditShow denied commands from the last hour:
runok audit --action deny --since 1hShow entries for git commands in JSON format:
runok audit --command git --jsonShow entries from a specific date range with a custom limit:
runok audit --since 2026-03-01 --until 2026-03-07 --limit 100Output format
Section titled “Output format”In text mode (default), the output adapts to the terminal:
- TTY (interactive terminal): a column-aligned table with colored action labels. Commands are truncated to fit the terminal width. Entries are sorted oldest-first so the most recent entry appears at the bottom.
TIMESTAMP ACTION COMMAND2026-03-13 19:30:00 allow git status2026-03-13 19:31:00 deny rm -rf /- Non-TTY (piped): tab-separated values without colors or truncation, suitable for further processing.
Timestamps are displayed in local time in both modes.
In JSON mode (--json), each entry is a complete JSON object with the input command, the overall action, sandbox preset, metadata, and command_evaluations — a per-branch list described below.
command_evaluations
Section titled “command_evaluations”command_evaluations is the single canonical place runok records per-branch evaluation data. Single inputs produce one entry, compound (a && b) and pipelined (a | b) inputs produce one per branch in source order, and inputs with no runnable command (comment-only, parse failure) produce an empty array.
Each entry carries the rule-evaluation result (action, matched_rules) and the shell-level parse result (env, argv, redirects, pipe) side by side, so audit consumers can filter on the actual binary in one jq line:
runok audit --json | jq 'select(.command_evaluations[].argv[0] == "helmfile")'Compound example:
{ "command": "FOO=x echo hi && BAR=y cat /tmp/f", "command_evaluations": [ { "command": "echo hi", "action": { "type": "allow" }, "eval_type": "compound", "env": [{ "name": "FOO", "value": "x" }], "argv": ["echo", "hi"] }, { "command": "cat /tmp/f", "action": { "type": "allow" }, "eval_type": "compound", "env": [{ "name": "BAR", "value": "y" }], "argv": ["cat", "/tmp/f"] } ]}Fields:
command— The branch command as runok extracted it (redirects stripped, env prefix kept).action— Rule-evaluation result for this branch.matched_rules— Rules that matched. Omitted when empty.eval_type—"primary"for non-compound inputs;"compound"for branches ofa && b/a | b/ etc.env— InlineKEY=VALUEprefix.valueisnullfor the bareKEY= cmdform. Omitted when empty.argv— Command name plus arguments, with shell quotes resolved.argv[0]is the binary as written. Omitted when shell parsing could not produce an argv.redirects— Redirect operators (> file,2>&1,<<<here-strings,<<here-docs, etc.). Each entry hasredirect_type(input/output/dup),operator(the bare operator token; the here-doc delimiter and body are not captured),target(file or fd reference; empty for<</<<-), and optionaldescriptor. Omitted when empty.pipe—{stdin, stdout}flags indicating pipeline position. Omitted when both arefalse.
Per-CLI shaping (resolving binary vs subcommand, normalising mise shims, classifying -n as boolean vs value-taking) is intentionally left to the consumer because those rules differ per CLI.
Configuration
Section titled “Configuration”Audit logging is configured in the global runok.yml only. Audit settings in project or local override configs are ignored. See Configuration Schema for the full reference.
audit: enabled: true path: ~/.local/share/runok/ rotation: retention_days: 7Log storage
Section titled “Log storage”Audit entries are stored as JSONL files partitioned by date (audit-YYYY-MM-DD.jsonl) in the configured directory. Files are written with append-mode and file locking, so concurrent runok invocations are safe.
Old log files are automatically removed based on rotation.retention_days.
Related
Section titled “Related”- Configuration Schema —
audit— Full audit config reference. runok exec— Commands evaluated viaexecare logged.