Skip to main content

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:

SurfaceContents
verdictan eventsGovernance events for gateway requests, such as verdicts and reason codes
verdictan historyCaptured conversation sessions, when capture is on
verdictan trailActors, resources, changes, times, and hash links for control-plane actions

Before you start​

  • A CLI credential: VERDICTAN_API_TOKEN, or a session from verdictan auth login.

  • These permissions:

    TaskPermission
    lookup, export, verify --event-id, and verify --anchor-receipt without a windoworg:trail:read
    verify for 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 10

Result: 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​

FlagDescription
--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.
--jsonPrint 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 \
  --json

Copy 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​

FlagDescription
--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.
--deepAlso 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.
--jsonPrint 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:00Z

The CLI gets the organization public key from GET /v1/trail/public-key. Then it checks the file on your computer:

  1. The payload type is application/vnd.verdictan.trail-anchor.v1+json.
  2. The Ed25519 signature is valid for the public key.
  3. The Merkle algorithm is SHA-256, and the backend is s3_object_lock or filesystem_worm.
  4. 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​

FlagDescription
--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.

FormatContent
jsonlOne complete event object on each line.
jsonOne JSON array of complete event objects.
csvA 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.gz

While 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.jsonl

The 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​

  • lookup and export accept a window of at most 7 days. When you supply both times, the CLI stops with trail query window must not exceed 7 days or --start-time must be earlier than --end-time. When you supply only one time, the API checks the window and returns HTTP 400 (trail.window_too_large).
  • lookup and export accept only RFC 3339 timestamps. verify --start-time also accepts <n>h and <n>d.
  • --org-id must be a UUID. A different organization stops the command with authenticated organization is <id>, not <id>.
  • verify exits with an error when the status is not pass. 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 HTTP 400 (trail.archive_segments_incomplete).
  • With --deep, a missing record before the window gives HTTP 422 (trail.inbound_link_missing).
  • verify --event-id exits with event verification failed — missing record hash when the event has no hash.
  • export stops with no trail events matched the requested export window when 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​

SymptomCauseFix
api authorization failed (403) from verifyA window verification needs org:trail:admin.Ask an administrator for a role with org:trail:admin.
api validation failed (422) from verifyThe 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 verifyThe 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 lookupThe window is longer than 7 days.Supply --start-time and --end-time less than 7 days apart.
anchor receipt DSSE signature verification failedThe 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​