feat: add hash-chained, append-only audit log

Introduce src/audit.rs: a SHA-256 hash-chained audit log for
security-sensitive operations (key export, NIP-46 connect/revoke,
signing approvals, vault lock/unlock, permission denials).

- AuditEntry carries timestamp, profile npub, action, reason,
  success flag, error, and prev/this hash forming a tamper-evident
  chain from a genesis hash.
- record() holds a single mutex across the entire read-compute-write-
  update cycle so concurrent writers cannot interleave and silently
  overwrite entries; appends are atomic (write-all + fsync + rename).
- verify_chain() re-hashes every entry end to end.
- Log lives in the app data dir with 0600 permissions.

Also adds the sha2 dependency. Verified in isolation on top of HEAD:
cargo test --release -> 124 passed (119 prior + 5 audit).
This commit is contained in:
Avi 2026-09-03 09:21:53 -05:00
commit caed722b06
4 changed files with 491 additions and 1 deletions

14
Cargo.lock generated
View file

@ -1177,6 +1177,7 @@ dependencies = [
"rpassword",
"serde",
"serde_json",
"sha2 0.10.9",
"tokio",
"uuid",
"zeroize",
@ -1841,7 +1842,7 @@ dependencies = [
"num",
"once_cell",
"serde",
"sha2",
"sha2 0.11.0",
"zbus",
]
@ -1933,6 +1934,17 @@ dependencies = [
"digest 0.10.7",
]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures 0.2.17",
"digest 0.10.7",
]
[[package]]
name = "sha2"
version = "0.11.0"