Security
The audit export, and how to check it without MoxiVue
An audit export is a folder of plain files: the account's signed log, the machines' signed records, readable lines for your own systems, and the session recordings if you ask. This page says what is in each file and what is signed, so that anyone can check an export with their own tools instead of ours.
A ready-made check in plain Python: verify-audit5.py.
The folder
moxivue audit export --dir <folder> writes what this console may read of the account's audit trail into a new folder. Add --format jsonl, --format csv or both for the readable lines, and --recordings for the session recordings. The export itself is written into the audit trail first.
| File | What it is |
|---|---|
log.mxlog | The account's signed log, as this console verified it, from its first entry, with the checkpoints both witnesses cosigned |
records.canon | Every sealed record of the machines this console may read, exactly as the Dispatcher keeps them, and the action records of the consoles that asked (for example who read a machine's stored history) |
audit.jsonl, audit.csv | The audit items in those records, as this console opened them, one per line or row: time, whether the machine or the asking console wrote it, machine, kind, the console it concerns, path, session, reason and details |
recordings/<session>.cast | With --recordings: the session recordings this console may open, as asciicast v2 files |
MANIFEST.json | The format (moxivue/audit-export/v5), the account, the exporting console, when, the number of records, action records and lines, and the SHA-256 of every file; signed by the exporting console |
moxivue export verify <folder> checks a folder with no account and no network: the manifest's signature by a console of the log and its hashes, the log from its first entry with the witnesses' keys built into the app, and every record and action record against that log, without opening them. moxivue export play <folder> <session> plays a recording from it. The manifest is signed by the exporting console with its log signing key, so the file list, the counts and the time cannot be changed afterwards either; the log and the records carry their own signatures as well.
The log
Every structure that is signed or hashed uses one canonical encoding, a strict subset of deterministic CBOR with integers only, so the same content always has the same bytes. Each entry carries its kind, a format version, the cosigned checkpoint it was made on, and the signatures its kind needs: the signer's log signing key, and for a change that needs it, a separate confirmation entry from another console. Every signature names its purpose with a label of the form moxivue/<purpose>/v1, and counts only when both halves of the key verify.
- The chain. Each leaf names its position and the hash of the leaf before it. The leaves form an RFC 6962 Merkle tree; a checkpoint names the size and the root of that tree in the C2SP checkpoint format, cosigned by both witnesses with their times. A checkpoint whose root differs from the tree the log builds is a fork, and the check fails.
- Whose key. Keys enter the log only through entries: the first entry (the genesis) carries the first console's keys and the recovery paper's public key; every join carries the new device's public keys with a proof that it holds them. A public key that has been in the log once is refused if it appears again. The account fingerprint is the SHA-256 of the genesis, 64 hexadecimal digits.
- Who may do what. Every rule of the apps' rules core is applied from the first entry: roles and reach, who may propose, confirm or refuse what, the set-up shape, persons, generations and their exact recipients, joins and install tokens (one use, expiry, revocation), settings versions, SSH grants, recovery requests and their waiting time, rotations. An authentic entry that breaks a rule stays in the log (a cosigned log cannot drop it) and has no effect; the check names it with its rule, and the export does not verify.
The records
A record is one batch of what a machine recorded, including its audit records of every view, session, forward and refusal it served. Its header is in clear: account, machine, place, generation, readers period and sequence number. Its body is sealed to the readers key of that place and period, and the machine signs header and body with its record key. Sequences go up by one per machine and kind, so a record the Dispatcher kept back shows as a gap. The root executor's records are signed with the executor's own key. An action record is the asking console's own signed account of what it asked, kept next to the machine's records.
The script
verify-audit5.py does the check described here in plain Python, using only the standard library. Every signature algorithm it needs is written out in it, so it can be read; it uses no MoxiVue code. Run it on an export:
moxivue audit export --dir audit-2026
python3 verify-audit5.py audit-2026/log.mxlog --records audit-2026/records.canon
It prints how many entries it verified from the genesis and how many are in cosigned checkpoints; with --records, how many records and action records it checked against the log, and which record sequences are missing. Exit status 0 means verified, 1 not verified (with the first failing entry and its rule), 2 a usage error or an unreadable file; --json prints the result as JSON. The same rules are checked in the app's own code and in this script against shared test logs and signed test vectors on every change, and both must give the same verdict.
What a check shows, and what it does not
It shows that the log was built by the account's own devices under the account's rules, that no entry was changed, removed or reordered, that both witnesses cosigned what it covers, and that each record came from a machine of the log, signed with the record key it held then, in its place and in order. It does not open the records: it holds no keys. It does not show that the export is the newest state of the account: compare the size of the log with what moxivue witness status shows on one of your consoles. And it shows what a machine signed, not that the machine told the truth: a machine that was taken over could leave out its own records; it cannot forge another device's.