Generic webhook AuditSink, the first concrete sink (F8.5)
Your AI's guard dog to stop it from going rogue.
Brought to you by:
doberman
Originally created by: fu351
Originally owned by: Maqbool61
Doberman defines an AuditSink seam (storage/sinks.py) but ships no concrete sink, so every deployment that wants its decision log off-box has to write one. Add the reference implementation: a webhook forwarder.
Behavior
.doberman/audit_webhook.yaml (url, optional auth_env naming an env var whose value becomes the Authorization header, optional timeout_s). No file, or a malformed one, means the sink simply does not exist.emit() runs on the decision path and is synchronous, so it must only append the record to a bounded queue; a daemon worker thread POSTs with stdlib urllib.request. Queue overflow drops oldest and counts.emit() was handed. It is already redacted upstream; the sink adds nothing and reads nothing else.emit_to_sinks consults built-in sinks after plugin discovery, with the same raising-sink isolation.Tests must prove
emit() returns before any network I/O).Honest scope: best-effort local buffering. Records lost on overflow or process exit are lost; this is a bridge to your own log pipeline, not a delivery guarantee.
Originally posted by: Maqbool61
Can i work on this?
Originally posted by: fu351
Yes go ahead! I've assigned the issue to you, looking forward to reviewing your PR
Ticket changed by: fu351