download-audit-logs
Copy a workspace's audit log files into a local folder. The command downloads the signed .jsonl audit files
and the .log configuration-change files from the server's audit folder, and skips the files the folder already
holds. Run it on a schedule to keep an archive of the audit trail off the server, then check the archive with
verify-audit-log.
It authenticates with a Library Token, not an administrator session. For what the files contain and why they should leave the server, see Audit logs.
Syntax
Usage: curiosity-cli download-audit-logs --server <url> --token <token> --output <folder> [--from <yyyy-MM-dd>] [--to <yyyy-MM-dd>] [--timeout <secs>]
# Everything the server holds
curiosity-cli download-audit-logs \
--server https://my-workspace.example.com/ \
--token $CURIOSITY_TOKEN \
--output /mnt/archive/curiosity-audit
# September only
curiosity-cli download-audit-logs -s https://my-workspace.example.com/ -t auto \
-o ./audit --from 2026-09-01 --to 2026-09-30
Options
| Option | Description |
|---|---|
--server |
Workspace URL. Alias -s. Required. |
--token |
Library Token (Manage → Access → Tokens, Add token → Library), or auto for one saved with store-token. Alias -t. Required. |
--output |
Folder to download into. Created if missing. Alias -o. Required. |
--from |
First day to download, as yyyy-MM-dd, inclusive. Default: no lower bound. |
--to |
Last day to download, as yyyy-MM-dd, inclusive. Default: no upper bound. |
--timeout |
Request timeout in seconds. Default 90. See Common Options. |
| Exit code | Meaning |
|---|---|
0 |
Every file in the range is in the output folder. |
| non-zero | The command failed, for example because the server could not be reached, the token was refused, or a date could not be parsed. |
Example output
Downloaded 2026-10-14_audit_logs_003.jsonl (412.6 KB)
Downloaded 2026-10-15_audit_logs_000.jsonl (88.1 KB)
Downloaded 2026-10-15_audit_config_logs_000.log (2.3 KB)
Downloaded 3 file(s) (503.0 KB) to '/mnt/archive/curiosity-audit', 214 unchanged.
One line per file it downloaded, then a summary with the number of files it skipped.
What it downloads
- Every file in the server's audit folder (
MSK_AUDIT_LOG_PATH) with a.jsonlor.logextension: the audit files, the configuration-change files, and any replica files that are on that server's disk. - Only what the server you point it at holds. A read-only replica writes its audit files on its own disk. To archive them, run the command against the replica too.
- The date range is matched against the date at the start of each file name, which is the server's local date
the file was started on (
2026-09-24_audit_logs_000.jsonlis 24 September). A file whose name does not start with a date is compared by its last-modified date, in UTC.
Running it again
The command is incremental. Run it as often as you like against the same folder:
- A file is skipped when the output folder already has a file with the same name and the same length in bytes. Audit files are only ever appended to, so a file of the same length has the same content.
- A file with a different length is downloaded again and replaced. The server has written more to it since the last run. This is normally the file the server is currently writing to.
- A download is written to
<name>.partialand renamed into place only when it is complete. An interrupted run leaves no truncated file that the next run would mistake for a finished one; the next run downloads the file again. - Files deleted on the server are never deleted locally. The workspace prunes old configuration-change files, and you may rotate the audit folder yourself. The archive keeps what it already has.
A file that is still being written is downloaded as it stood when the request was made. The next run picks up the rest.
Archiving on a schedule
Download, then verify the whole archive, and alert when either step fails. Verifying the whole folder rather than the new files alone lets each file's first entry be checked against the file before it.
#!/usr/bin/env bash
set -euo pipefail
ARCHIVE=/mnt/archive/curiosity-audit
REPORTS=/mnt/archive/reports
curiosity-cli download-audit-logs -s https://my-workspace.example.com/ -t auto -o "$ARCHIVE"
curiosity-cli verify-audit-log "$ARCHIVE" --strict --json > "$REPORTS/audit-$(date +%F).json"
# Every hour, at 17 minutes past
17 * * * * /opt/curiosity/archive-audit.sh || echo "Audit archive failed" | mail -s "Curiosity audit" security@example.com
Store the token once, as the user the job runs as, so the job can pass -t auto:
curiosity-cli store-token -s https://my-workspace.example.com/ -t "$CURIOSITY_TOKEN"
Then, for a report or a SIEM, convert the archive with convert-audit-log, which can run
the same check first with --verify.
The copy only protects the trail if it leaves the server before anyone could rewrite the originals. Keep the archive on storage the workspace's administrators cannot write to, such as a separate host, WORM storage or a bucket with object lock, and see What the chain does not prove.
Requirements
- A workspace version with the Library endpoints
list-audit-log-filesanddownload-audit-log-file. An older server answers404. - A Library Token. Anyone holding it can download the audit files, which contain user names, email addresses and
AI chat content. Issue a token for this purpose alone, and store it with
store-tokenor in your scheduler's secret store.
Related
verify-audit-log: check the downloaded files' hash chain.convert-audit-log: turn them into CSV, TSV or JSON.- Audit logs: where the files are written and what an entry contains.