Every command that reaches a jaque process is written to a second, append-only log before it is forwarded or refused: who sent it, what it was, and whether it was accepted. This page states what is recorded, where it goes, and what a refused write looks like.
1. What is recorded
One line per command that reaches the process: the time, the source
(api for a command submitted over the command API, extcmd for one
read off the external command FIFO), who sent it (name and role, when
the API authenticated the caller), the peer address, the RPC or verb
invoked, the command itself as JSON, and whether it was accepted or
rejected, with the reason when it was rejected.
A caller refused before the command is even parsed -- a bad token, a role that cannot issue it -- is recorded too, with no command body to show for it. Passive check results are not commands: they carry no sender's intent to act, only an observation, and they are not recorded here.
2. Where it goes
-audit memory, the default, keeps the last 1024 records in process
memory: a ring buffer, lost on restart.
-audit file:///var/lib/jaque/audit writes one JSON line per record to
files under that directory, rotated at 64 MB; rotated files older than
-audit-retention (default 90 days) are removed.
Either way the trail is per process. It is never replayed into state and never folded into a projection -- it answers "who did this", not "what is true now".
3. Reading it back
The trail is served back over the API, not read from disk or memory
directly: AdminService.ListAuditRecords returns records newest first
to admin identities, the same role gate the rest of AdminService uses.
See Admin service for the request and
response shape. The file backend serves from whatever files it has
still retained; the memory backend serves from its ring, so a restart
still loses the same records the ring always lost.
4. A sample line
{"at":"2026-09-07T10:32:11Z","source":"api","principal":{"name":"jdoe","role":"operator"},"peer":"10.0.4.12:53214","rpc":"/jaque.v1.CommandService/AcknowledgeProblem","command":{"Target":{"object":"web-01/http"},"Sticky":false,"Author":"jdoe","Comment":"investigating"},"outcome":"accepted"}
5. When it cannot write
An audit record that cannot be written refuses the command it would have
recorded: the caller gets UNAVAILABLE back with the message "audit log
unavailable", and jaque_audit_write_errors_total climbs. A full disk
under -audit file://... shows up this way on purpose -- a command
nobody can prove was issued is worse than a command temporarily refused.
6. Security considerations
The audit file is the record of who did what: it carries the peer
address and the caller's name for every command issued against this
process. Own the directory to the service user, set its mode to 0750,
and ship it to wherever the rest of the process's logs go.