Skip to main content

Verify workflow execution history

When workflow verification is enabled for a project, Catalyst cryptographically signs blocks of events for each workflow's execution history as it runs. That lets an operator or auditor confirm a workflow's history is intact — and produce independent proof that a given action took place. Verification runs automatically whenever you read an execution.

Signing is set when the project is created and cannot be changed later; executions in a project without it are reported as unsigned. For what the feature is and how the signature chain works, see Tamper-evident attestation.

This page covers the CLI, which can also produce portable proof that verifies offline. To inspect the same verification results visually, use the Catalyst console — see Verify execution history in the console.

Verification states

  • verified — the history is signed and intact.
  • tampered — the stored history no longer matches its signature; it was altered.
  • unsigned — no signature covers the history or event: signing is not enabled for the project, or the newest events of a running instance have not been sealed into a signature block yet.
  • unverified — the check could not run. This is not evidence of tampering; the verification.error field in the output reports why (for example, the trust bundle was unavailable).

Spot tampered executions across a project

List a project's executions. Only tampered executions are flagged; a blank verification cell means nothing was flagged:

diagrid workflow list --project <project>

To review one, note its workflow ID and the ID it runs under, and continue below.

Verify a single execution

diagrid workflow get <workflow-id> --id <id> --project <project>

The output includes a verification section with the overall verdict, the signature blocks covering the history, and the identity that signed each block; every event in the history is also annotated with its own verificationStatus:

verification:
status: verified
eventCount: 12
signedEventCount: 12
blocks:
- index: 0
startEventIndex: 0
eventCount: 12
certificateIndex: 0
status: verified
certificates:
- index: 0
spiffeId: spiffe://<region-trust-domain>/ns/prj-<project-id>/orders

This answers "is this workflow's history intact, and who signed it?" in one command.

Produce portable proof

To hand an auditor a self-contained receipt they can check independently of the running system, export the execution as a signed archive. Only terminal executions (completed, failed, or terminated) can be exported:

diagrid workflow archive export <workflow-id> --id <id> --project <project> --out receipt.json

Verify it against the project's trust bundle:

diagrid workflow archive verify receipt.json --project <project>

To read the archived history without checking signatures:

diagrid workflow archive print receipt.json

Verify offline

A signed archive is self-contained except for the trust bundle it anchors to. Export that bundle once, then verify with no further connection to Catalyst:

# capture the project's trust bundle
diagrid workflow archive trust-anchor --project <project> --out trust.pem

# verify using the on-disk bundle — no network needed
diagrid workflow archive verify receipt.json --trust-anchor trust.pem
note

Export the trust bundle at the same time as the archives you intend to verify with it, and store them together. Trust roots rotate over time, so a bundle captured later may not match older archives — that is expected, not tampering.

Reference

For the full command options and output, see the diagrid workflow command reference. To inspect verification visually in the console, see Operate workflows.