Files
ops-warden/workplans/WARDEN-WP-0022-audit-trail-and-activity.md
tegwick f47d632d8e Add July INTENT↔SCOPE gap analysis and WARDEN-WP-0023 alignment closeout
Persist the 2026-07-01 assessment, register the alignment workplan with
tasks for INTENT refresh, production integration coordination, broker UX,
and catalog promotion. Promote WP-0022 to ready and update SCOPE links.
2026-07-01 23:27:14 +02:00

4.5 KiB

id, type, title, domain, repo, status, owner, topic_slug, planning_priority, planning_order, created, updated, state_hub_workstream_id
id type title domain repo status owner topic_slug planning_priority planning_order created updated state_hub_workstream_id
WARDEN-WP-0022 workplan Audit trail + `warden activity` — one place to see what ops-warden did infotech ops-warden ready claude custodian high 22 2026-07-01 2026-07-01 fc8afa28-68a7-4250-a19e-9754829f0cd5

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

id: WARDEN-WP-0022-T01
status: todo
priority: high
state_hub_task_id: "7f8f768a-4c62-4096-bad8-912cea0f35a7"
  • 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

id: WARDEN-WP-0022-T02
status: todo
priority: high
state_hub_task_id: "e7ae4037-ca79-4557-81f0-bfb8478ff647"
  • 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

id: WARDEN-WP-0022-T03
status: todo
priority: high
state_hub_task_id: "4439bdd8-1461-47df-8b0b-048df7384a68"
  • 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

id: WARDEN-WP-0022-T04
status: todo
priority: medium
state_hub_task_id: "bdfb8703-7a79-43e7-913b-19d61722f164"
  • 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)