CLI
verdictan trail
Use verdictan trail to find who changed what in Verdictan, and when. Trail records control-plane actions, such as a new user, a deleted token, or a changed role. Each record has a hash that links it to the previous record, so you can verify that stored records did not change.
Trail does not contain the verdicts for model requests. Each surface holds different records:
| Surface | Contents |
|---|---|
verdictan events | Governance events for gateway requests, such as verdicts and reason codes |
verdictan history | Captured conversation sessions, when capture is on |
verdictan trail | Actors, resources, changes, times, and hash links for control-plane actions |
Before you start
-
A CLI credential:
VERDICTAN_API_TOKEN, or a session fromverdictan auth login. -
These permissions:
Task Permission lookup,export,verify --event-id, andverify --anchor-receiptwithout a windoworg:trail:readverifyfor a time windoworg:trail:admin -
The region that holds the records. Each command uses the region of the profile, or the value of
--region.
The credential selects the organization. You cannot select a different organization with a flag. Each subcommand accepts --org-id <uuid> as a safety check: the CLI reads GET /v1/whoami and stops before it sends the Trail query when the authenticated organization has a different ID.
Read recent account activity
verdictan trail lookup --limit 10Result: a table with the columns EVENT_TIME, EVENT_NAME, RESOURCE_TYPE, ACTOR, and SOURCE_IP, followed by Total: <n> event(s). Without a time window, the API returns events from the last 24 hours, newest first.
Compare the actor, the event name, the resource, and the time with the change that you investigate. If the window has no events, the command prints No trail events found.
verdictan trail lookup
verdictan trail lookup prints the Trail events for one request ID, or one page of events that match filters.
Usage
verdictan trail lookup --request-id <uuid> [--json]
verdictan trail lookup [FILTERS] [--start-time <rfc3339>] [--end-time <rfc3339>] [--limit <n>] [--json]Options
| Flag | Description |
|---|---|
--request-id <uuid> | Return all events for one HTTP request. The CLI sends GET /v1/trail/events/lookup and ignores the filters, the window, and --limit. |
--event-source <source> | Return only events from one source, such as identity_access or governance. |
--event-name <name> | Return only events with one name, such as CreateUser or DeleteToken. |
--resource-type <type> | Return only events for one resource type, such as User or Team. |
--resource-id <id> | Return only events for one resource ID. |
--actor-arn <arn> | Return only events by one actor. |
--start-time <rfc3339> | Start of the window. The default is 24 hours before the end time. |
--end-time <rfc3339> | End of the window. The default is now. |
--limit <n> | Number of events, from 1 to 1000. The default is 100. |
--org-id <uuid> | Stop unless the authenticated organization has this ID. |
--json | Print the API response as JSON. |
--config <path>, --api-url <url>, --profile <name>, --region <region> | Standard connection and profile overrides. |
Without --request-id, the CLI sends GET /v1/trail/events. The window can be at most 7 days.
Examples
# All events for one request
verdictan trail lookup --request-id "replace-with-request-uuid"
# Identity changes to one role in the last 24 hours
ROLE_ID="replace-with-role-id"
verdictan trail lookup \
--event-source identity_access \
--resource-type Role \
--resource-id "$ROLE_ID"
# Token deletions in a fixed window, as JSON
verdictan trail lookup \
--event-name DeleteToken \
--start-time 2026-07-01T00:00:00Z \
--end-time 2026-07-08T00:00:00Z \
--jsonCopy the role ID from the role in the Console, or from verdictan role list.
With --json, the response has an events array, a next_cursor, and a result_count. Each event has fields such as event_id, event_time, event_source, event_name, actor_type, actor_arn, actor_email, source_ip, request_id, request_method, request_path, response_status, resource_type, resource_id, change_record, sequence_number, previous_hash, and record_hash.
lookup prints one page only. It has no --cursor flag. To read all events in a window, use verdictan trail export.
verdictan trail verify
verdictan trail verify checks the integrity of stored Trail records. It has three modes: a window verification on the control plane, a single-event check, and an anchor-receipt check.
Usage
verdictan trail verify [--start-time <rfc3339|duration>] [--end-time <rfc3339>] [--deep] [--json]
verdictan trail verify --event-id <uuid> [--json]
verdictan trail verify --anchor-receipt <path> [--start-time <rfc3339|duration>] [--end-time <rfc3339>] [--json]Options
| Flag | Description |
|---|---|
--start-time <rfc3339|duration> | Start of the window. Use an RFC 3339 timestamp, or a positive integer followed by h or d, such as 24h or 7d. The default is 7 days before now. |
--end-time <rfc3339> | End of the window. The default is now. |
--deep | Also get each event in the window, calculate its hash again, and check the sequence numbers and the previous-hash links. |
--event-id <uuid> | Check one event. You cannot use it with --start-time, --end-time, --deep, or --anchor-receipt. |
--anchor-receipt <path> | Verify a local anchor receipt file. See Verify an anchor receipt. |
--org-id <uuid> | Stop unless the authenticated organization has this ID. With --anchor-receipt, also stop unless the receipt has this organization. |
--json | Print the result as JSON. |
--config <path>, --api-url <url>, --profile <name>, --region <region> | Standard connection and profile overrides. |
A window verification sends POST /v1/trail/verify. The control plane loads the signed digest records for the window and checks these items:
- The archive segments cover the complete window.
- Each digest has a valid DSSE signature from a known Trail signing key.
- Each digest links to the previous digest.
With --deep, the control plane also loads each event in the window. It calculates each record hash again, checks that the sequence numbers have no gaps, and checks each previous-hash link. It also checks that the first event links to the event before the window.
Examples
# Standard verification of the last 7 days
verdictan trail verify --start-time 7d
# Deep verification of a fixed window, as JSON for the evidence file
verdictan trail verify \
--org-id "replace-with-your-org-uuid" \
--start-time 2026-07-01T00:00:00Z \
--end-time 2026-07-15T00:00:00Z \
--deep \
--json
# Check that one event has a stored record hash
verdictan trail verify --event-id "replace-with-event-uuid"When the verification passes, text mode prints ✓ Hash chain verified, followed by the number of events and digest records checked, the sequence range, and Status: pass. When it fails, the command prints ✗ Hash chain verification FAILED, the status, and each sequence gap as Expected sequence <n>, actual <n>.
With --json, the response has these fields: status (pass or fail), chain_integrity, digests_verified, events_verified, first_sequence, last_sequence, gaps, and verification_time_ms.
The single-event check sends GET /v1/trail/events/<id>. It confirms only that the event has a record_hash. It does not calculate the hash again and does not check the links. On success, it prints ✓ Event record hash present and Status: hash_present.
For a review that covers more than one window, verify adjacent windows with fixed boundaries, and keep each result.
Verify an anchor receipt
An anchor receipt is a DSSE envelope that a deployment publishes to an s3_object_lock or filesystem_worm backend. It records the Merkle root of the Trail records in a window.
verdictan trail verify --anchor-receipt trail-anchor-2026-07-01.json
verdictan trail verify \
--anchor-receipt trail-anchor-2026-07-01.json \
--start-time 2026-07-01T00:00:00Z \
--end-time 2026-07-02T00:00:00ZThe CLI gets the organization public key from GET /v1/trail/public-key. Then it checks the file on your computer:
- The payload type is
application/vnd.verdictan.trail-anchor.v1+json. - The Ed25519 signature is valid for the public key.
- The Merkle algorithm is
SHA-256, and the backend iss3_object_lockorfilesystem_worm. - The Merkle root, calculated again from the leaf hashes, is the same as the root in the receipt.
Without a window, the command prints ✓ Anchor receipt verified and the receipt details. With a window, the CLI also checks that the receipt window overlaps the verification window. Then it runs the window verification. With --json, the result has an anchor object.
verdictan trail export
verdictan trail export reads all Trail events in a window, page by page, and writes them to one file.
Usage
verdictan trail export --output <path> [--format <json|jsonl|csv>] [--start-time <rfc3339>] [--end-time <rfc3339>] [--event-source <source>] [--event-name <name>]Options
| Flag | Description |
|---|---|
--output <path> | Mandatory destination file. When the name ends in .gz, the CLI compresses the file with gzip. |
--format <json|jsonl|csv> | File format. The default is jsonl. |
--start-time <rfc3339> | Start of the window. The default is 24 hours before the end time. |
--end-time <rfc3339> | End of the window. The default is now. |
--event-source <source> | Export only events from one source. |
--event-name <name> | Export only events with one name. |
--org-id <uuid> | Stop unless the authenticated organization has this ID. |
--config <path>, --api-url <url>, --profile <name>, --region <region> | Standard connection and profile overrides. |
The CLI sends GET /v1/trail/events with 1000 events on each page, and follows next_cursor to the last page. The window can be at most 7 days.
| Format | Content |
|---|---|
jsonl | One complete event object on each line. |
json | One JSON array of complete event objects. |
csv | A header row, then one row for each event with the columns event_id, event_time, event_name, event_source, resource_type, resource_id, actor_email, actor_arn, source_ip, request_method, and request_path. The CSV does not contain the hashes or the change records. |
Examples
# One week as JSON Lines
verdictan trail export \
--start-time 2026-07-01T00:00:00Z \
--end-time 2026-07-08T00:00:00Z \
--output evidence.jsonl
# The same window as compressed CSV
verdictan trail export \
--start-time 2026-07-01T00:00:00Z \
--end-time 2026-07-08T00:00:00Z \
--format csv \
--output evidence.csv.gzWhile it reads pages, the command shows a progress count on standard error. When it is complete, it prints Exported <n> events to <path>. To verify a JSON Lines file, count its lines. The count is the same as <n>:
wc -l evidence.jsonlThe CLI creates the destination file only after it reads all pages and finds at least one event. Record the command parameters, the file digest, the export time, and the reviewer with the evidence. Audit records can contain sensitive metadata, so store the file according to your retention and access policy.
Limits and failure behavior
lookupandexportaccept a window of at most 7 days. When you supply both times, the CLI stops withtrail query window must not exceed 7 daysor--start-time must be earlier than --end-time. When you supply only one time, the API checks the window and returns HTTP400(trail.window_too_large).lookupandexportaccept only RFC 3339 timestamps.verify --start-timealso accepts<n>hand<n>d.--org-idmust be a UUID. A different organization stops the command withauthenticated organization is <id>, not <id>.verifyexits with an error when the status is notpass. In JSON mode, it prints the response first.- A window without digest records gives HTTP
422(trail.empty_verification_window). A window that the archive segments do not cover gives HTTP400(trail.archive_segments_incomplete). - With
--deep, a missing record before the window gives HTTP422(trail.inbound_link_missing). verify --event-idexits withevent verification failed — missing record hashwhen the event has no hash.exportstops withno trail events matched the requested export windowwhen the window is empty. It also stops when the API returns an empty page with a cursor, or the same cursor two times. In these cases, it does not create or change the destination file.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
api authorization failed (403) from verify | A window verification needs org:trail:admin. | Ask an administrator for a role with org:trail:admin. |
api validation failed (422) from verify | The window has no signed digests. With --deep, the record before the window can also be missing. | Use a window that contains Trail activity, or start the window at an earlier digest. |
api request failed with status 400 from verify | The archive segments do not cover the window, or a time is not RFC 3339. | Use a shorter window that the archive covers, and check the timestamp format. |
api request failed with status 400 from lookup | The window is longer than 7 days. | Supply --start-time and --end-time less than 7 days apart. |
anchor receipt DSSE signature verification failed | The receipt is from a different organization or key, or the file changed. | Get the receipt again from the anchor backend, and check the organization. |
anchor receipt window [...] does not overlap verification window [...] | The receipt covers a different time. | Use the window that the receipt names. |
Next steps
- Trail and Audit Evidence: learn how Trail records, digests, and anchors work.
- Export Evidence for a Review: put Trail and event exports into one evidence package.
- verdictan events: read the governance events for gateway requests.
- Permissions Reference: grant
org:trail:readandorg:trail:admin.