Skip to main content

Verify workflow execution history

When workflow history signing 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 Execution history verification.

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.