From c96b27051fef3f91f564cacd02a07abb31846668 Mon Sep 17 00:00:00 2001 From: tegwick Date: Wed, 1 Jul 2026 19:58:28 +0200 Subject: [PATCH] plan(WARDEN-WP-0022): audit trail + `warden activity` Draft workplan for a unified, metadata-only audit log of every ops-warden action (sign, access proxy, worker send/tick) and a single `warden activity [--days N] [--kind] [--json]` command to read it. Secret-material guard so no value ever lands in the audit; folds in the existing signatures.log / access-audit.log; optional --hub for the progress-note narrative. Co-Authored-By: Claude Opus 4.8 --- ...WARDEN-WP-0022-audit-trail-and-activity.md | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 workplans/WARDEN-WP-0022-audit-trail-and-activity.md diff --git a/workplans/WARDEN-WP-0022-audit-trail-and-activity.md b/workplans/WARDEN-WP-0022-audit-trail-and-activity.md new file mode 100644 index 0000000..4b0fa8e --- /dev/null +++ b/workplans/WARDEN-WP-0022-audit-trail-and-activity.md @@ -0,0 +1,113 @@ +--- +id: WARDEN-WP-0022 +type: workplan +title: "Audit trail + `warden activity` — one place to see what ops-warden did" +domain: infotech +repo: ops-warden +status: proposed +owner: claude +topic_slug: custodian +planning_priority: high +planning_order: 22 +created: "2026-07-01" +updated: "2026-07-01" +--- + +# WARDEN-WP-0022 — Audit trail + `warden activity` + +**Problem:** ops-warden's actions are recorded in scattered places — `signatures.log` +(cert signs), `access-audit.log` (proxy fetches), the systemd journal (worker ticks), and +State Hub progress notes (the narrative). There is **no single, structured audit trail** +and no one command to answer *"what did ops-warden do in the last N days?"*. For a security +steward, a coherent, metadata-only audit record is table stakes. + +**Goal:** a unified, append-only audit log that captures **every** ops-warden action with a +common shape (never a secret value), and a single `warden activity` command to read it. + +**Non-negotiable (this is a security tool's audit):** the audit record holds **metadata +only** — actor/subject, action, target/path id, decision id, TTL, outcome, timestamp — and +**never** a token, key, cert body, or other secret. A secret-material guard rejects any +event field that looks like a value (mirrors the catalog `_assert_no_secret_material`). + +**Posture:** read/append-only, in-boundary (local logs + optional hub read). Tamper-evident +hash-chaining is noted as an optional hardening for when the ecosystem reaches testing. + +**Relates to:** WP-0014 (`access-audit.log`), the SSH lane (`signatures.log`), WP-0020/0021 +(the worker). Linger is now enabled (worker survives logout); full logged-out value also +needs the State Hub + tunnels to be login-independent (State Hub → railiance01, +`cust-wp-0011`). + +--- + +## Tasks + +### T1 — Unified audit event log + +```task +id: WARDEN-WP-0022-T01 +status: todo +priority: high +``` + +- [ ] `src/warden/audit.py`: append-only JSONL at `state_dir/audit.jsonl`. Common event + schema — `ts`, `kind` (`sign`|`access`|`worker`), `action`, `subject`, `target`, + `decision_id`, `outcome`, `source`. `record_event(**meta)` with a secret-material + guard (reject token prefixes / high-entropy runs) so no value can ever land here. + `read_events(*, since, kinds)` for the reader. +- [ ] Log rotation / bound (size or age) so it stays manageable. + +### T2 — Instrument the actions + +```task +id: WARDEN-WP-0022-T02 +status: todo +priority: high +``` + +- [ ] Emit an audit event from each ops-warden action: `warden sign` (cert issued — + actor, type, ttl, backend, policy_decision_id), `warden access --fetch/--exec` + (proxy — need id, owner, decision id), and the worker (`approve` → reply sent to X; + tick → triage summary N/drafted/escalated). Fold the existing `signatures.log` / + `access-audit.log` in as sources (keep back-compat; don't drop a record). +- [ ] Assert no secret value reaches the audit in any path (tests). + +### T3 — `warden activity` command + +```task +id: WARDEN-WP-0022-T03 +status: todo +priority: high +``` + +- [ ] `warden activity [--days N] [--kind sign|access|worker] [--json] [--hub]` — a single + chronological view merging the audit log (and, for back-compat, `signatures.log` / + `access-audit.log`); `--hub` also pulls recent ops-warden State Hub progress notes for + the narrative. Human table by default; stable `--json` for agents. + +### T4 — Tests, runbook, SCOPE + +```task +id: WARDEN-WP-0022-T04 +status: todo +priority: medium +``` + +- [ ] Tests: audit append/read/rotation, the secret-material guard rejects values, the + instrumented actions emit events, `warden activity` filtering + `--json` shape. +- [ ] `wiki/AuditTrail.md` (what's recorded, the no-secret guarantee, how to query, the + linger + login-independence note). SCOPE entry. + +--- + +## Acceptance + +- Every ops-warden action (sign, access proxy, worker send/tick) appends a metadata-only + audit event; the secret-material guard is proven to reject values. +- `warden activity --days 3` answers "what did ops-warden do" in one command; `--json` + gives agents a stable shape. +- No secret value appears in the audit log, ever. + +## See also + +- `WARDEN-WP-0014` (`access-audit.log`), `WARDEN-WP-0020`/`0021` (the worker) +- `wiki/OperatorAccessAssist.md` (the metadata-only audit principle)