> Section: [7. Running it](https://jaque.sh/docs/deployment/overview.md)
> Next: ui/dashboard
> Index: https://jaque.sh/llms.txt


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](https://jaque.sh/docs/api/admin-service.md) 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

```json
{"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.
