Skip to content

Append-only audit log of approved requests and outcomes #6

@cuihtlauac

Description

@cuihtlauac

Problem

The only record of what sudo-proxy approved and ran is -v output on stderr (src/server.rs:518-522). It vanishes when the terminal closes. For a tool whose value proposition is "human in the loop," there is no durable record of which command was approved by which operator at what time, nor what the result was.

This matters most when something goes wrong: a misapproved rm, a config change that broke a service overnight, an unexpected exit code. The TUI prompt has been seen and dismissed; the only ground truth is what the daemon executed.

-v is also lossy by design: it prints a one-line summary of the request and skips the response entirely.

Proposal

Append-only JSONL log at $XDG_STATE_HOME/sudo-proxy/audit.log (default ~/.local/state/sudo-proxy/audit.log), mode 0600. Two records per approved execution, correlated by request id:

  • Request record at TUI-prompt time: id, time, host, session, pipeline, env keys (names only, not values — env may carry secrets), reason, privileged, resolved path of each stage's argv[0], and the TUI decision (approved/denied/timeout) with latency.
  • Response record at completion: id, per-stage exit_code, total wall-clock duration, stdout/stderr lengths and truncation flags. Do not log stdout/stderr contents — they may be huge or sensitive; lengths are enough to flag anomalies and join against external logs.

Hooks into src/server.rs request handling (around lines 408-522). Rotation is the OS's job (logrotate); the daemon just appends.

Things to consider:

  • Log denied and timed-out requests too, otherwise the log under-counts what the operator saw.
  • Whether to log unprivileged requests by default (probably yes — auditing the decision matters even when no escalation happened).
  • Failure mode if the log file can't be opened: refuse to start? log to stderr and continue? Probably the latter, with a one-time warning, so a broken state dir doesn't take the daemon down.
  • A small --audit-log PATH / --no-audit flag for operators who want to redirect or disable.
  • Clock source: use the wall-clock time field that's already on the request, not a fresh Instant::now(), so the log lines up with the request UUID's perceived time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions