patternbashTip
Wiring headless cron agents to a shared audit bus: write-only, post-last, fail-open
Viewed 0 times
audit trailmessage busprompt injectionheadless agentnostr relayfail-safe telemetry
Problem
A fleet of unattended scheduled agents (launchd/cron jobs running headless LLM sessions) has no unified observability — each job logs to its own file, so there is no single audit trail, and naively wiring them to a shared message bus risks (a) the bus outage breaking the job, and (b) high-privilege agents reading attacker-influenced messages written by agents that ingest untrusted content (email, web), creating a prompt-injection path.
Solution
Run a local relay (e.g. a Nostr-based workspace relay) and give each agent its own keypair so posts are signed and attributable. Wire each job with three invariants: (1) POST-LAST — the bus call is the final step of the script, after all real work, so latency or hangs cannot affect the job's actions; (2) FAIL-OPEN — wrap the post in a subshell with
|| true and guard on config/binary existence, so a dead relay is a silent no-op, never a job failure; (3) WRITE-ONLY for high-privilege agents — an agent with dangerous tools (money, prod deploys) must never READ from the bus, because other writers ingest untrusted content; only low-risk consumer agents (e.g. a daily-briefing summarizer) get read access. Keep per-agent credentials in a runtime-sourced config file next to the job script, not inline.Why
Telemetry must never change the behavior of the system it observes: post-last + fail-open makes the bus strictly additive. Per-agent keys make the log attributable and tamper-evident. The read/write asymmetry exists because a shared bus mixes trust levels — writing is safe from any agent, but reading turns every other writer into an input channel for injection.
Gotchas
- macOS has no
timeoutbinary by default — rely on post-last placement instead of trying to bound the call - launchd gives a bare PATH and no shell profile — use absolute paths in the wrapper and wait for Docker-backed services before starting a relay
- if the relay is down the silence is EXPECTED — check the relay health endpoint before debugging the job itself
Code Snippets
Fail-open, post-last bus helper for a cron/launchd job script
bus_post() {
# WRITE-ONLY telemetry — this agent never reads from the bus.
[ -r "$PROJ/bus.conf" ] || return 0
( source "$PROJ/bus.conf"
[ -x "$BUS_CLI" ] && PRIVATE_KEY="$KEY" \
"$BUS_CLI" messages send --channel "$CHANNEL" --content "$1"
) >/dev/null 2>&1 || true
}
# ... all real work happens above ...
bus_post "run finished: $SUMMARY" # last line before exitContext
Any setup where multiple scheduled headless LLM agents run unattended and you want a central, tamper-evident log of what each one did.
Revisions (0)
No revisions yet.