Skip to content

The offline verifier

The verifier is the verify mode of the appliance binary. It runs on the examiner’s own Windows, macOS or Linux computer, needs no network and no account, and trusts one value the examiner holds separately: the evidence key ID on the signed key registration sheet. Everything below is a real run of the main-branch binary on packs exported in dev mode.

  1. Get the key ID from the bank, on paper. The ISO prints the key registration sheet (Evidence › Verify › Key registration sheet) and signs it. It shows the organization, appliance serial, evidence key ID (64 hex characters) and checkpoint verifier key. File it with the workpapers. This sheet, not the pack, is the root of trust.

  2. Receive the original ZIP. Not a folder, and not a ZIP made again from a folder: the container is checked byte for byte and a re-made ZIP is MALFORMED. Safari unzips downloads unless “Open safe files after downloading” is turned off.

  3. Get the binary for your platform and check it against SHA256SUMS (see Platforms and builds).

appliance verify -trust <key ID from the sheet> pack.zip
appliance verify -trust cc911e1df79b8b7b97229eb8c163c1405b581680af2cb940386f74437c7aa524 pack.zipEVIDENCE PACK VERIFICATIONResult:            PASSVerified at:       2026-10-24T09:05:24ZPack fingerprint:  33f9acb1d1132b67e38b5bd0b2c35123f5b2032a84f8a034be6604fc338815f1Signer key ID:     cc911e1df79b8b7b97229eb8c163c1405b581680af2cb940386f74437c7aa524Trusted via:       trusted key IDAppliance:         DEV01 (version dev)Build digest:      67440c787f3f4a937137e06b54d84cabb5c6ff019e4034733f90e2dd1fd31983Period:            2026-07-26T04:00:00Z to 2026-10-25T04:00:00ZLog:               gigidlabs.com/appliance/DEV01, size 181Log root:          WQHNjvnRAxCGVYqbAizpIt2v6mD60suPkcokNrjkf0M=Entries:           181 (seq 0 to 180, 2026-10-24T08:50:26Z to 2026-10-24T08:57:52Z)Decisions:         9Reviews:           0Exceptions:        1Devices:           approved 8, needs_review 25, not_approved 1Coverage:          100.0% of source-days since install covered (covered 4)Assurance tier:    software_protectedDetection proofs:  coverageCrosswalk:         CIS Controls v8.1 / NIST CSF 2.0 / 12 CFR 30 App. B, 364 App. B, 748 App. A (2026-10)FIPS 140-3 mode:   offAnchored to:       CHECKPOINTS NOT ANCHOREDSeparation:        SINGLE-OPERATOR MODE (one person held Admin and Reviewer)History:           NOT CHECKED against an independent checkpointChecks:  1. Signing key is trusted (registration sheet or previous pack)   PASS     key cc911e1df79b8b7b97229eb8c163c1405b581680af2cb940386f74437c7aa524, trusted via trusted key ID  2. Manifest signature (DSSE, Ed25519) is valid                    PASS     Ed25519 signature over the manifest is valid  3. Every file matches its SHA-256 in the manifest                 PASS     18 files match their manifest digests  4. Checkpoint signature is valid and matches the manifest         PASS     checkpoint for gigidlabs.com/appliance/DEV01 at size 181 is signed by a trusted key  5. Every entry has a valid inclusion proof to the checkpoint      PASS     181 entries (seq 0 to 180) and 9 cited entries are in the signed log  6. History is consistent with earlier checkpoints                 NOT_CHECKED     NOT CHECKED: no independent checkpoint (previous pack, SIEM or email) was supplied; the pack's own consistency proofs from 1 earlier pack checkpoint(s) are valid  7. Recomputed totals match the manifest counts                    PASS     entries, decisions, reviews, exceptions, devices and coverage all match[exit 0]

Read it from the top:

  • Result: PASS and exit code 0. Every check that could run passed.
  • Pack fingerprint is SHA-256 of the manifest. The appliance logged the same value when the pack was exported, and later packs prove that entry.
  • Signer key ID equals the key ID on the sheet; Trusted via says how.
  • Entries, Decisions, Reviews, Exceptions, Devices, Coverage are recounted from the files, not copied from the manifest (check 7).
  • Assurance tier: software_protected: the evidence key is a file on the appliance, not in a TPM.
  • Anchored to: CHECKPOINTS NOT ANCHORED and History: NOT CHECKED: no checkpoint from outside the appliance was supplied, so check 6 could not prove that history before this pack was not rewritten. The pack can still pass; say so in the workpapers, or supply an anchor (step 3 below).
  • Separation: SINGLE-OPERATOR MODE: one person held both Admin and Reviewer when this demo was run.
  • FIPS 140-3 mode: off and version dev come from a local development build.

The run took 0.014 seconds for 181 entries.

One row of inventory.csv was changed from not_approved to approved inside the ZIP (with the container rebuilt carefully, since a plain re-zip is rejected first as MALFORMED):

appliance verify -trust cc911e1df79b8b7b97229eb8c163c1405b581680af2cb940386f74437c7aa524 pack-edited.zipEVIDENCE PACK VERIFICATIONResult:            TAMPEREDReason:            inventory.csv has SHA-256 00951cdee49cd0043f6c0b330b264e169f5145a4427582bbd913781b10a6e2b0, manifest says d1a167f91c009a0ede446cb27fd4b7f46653c20f11327be06d0949fdefa65532Verified at:       2026-10-24T09:05:24ZPack fingerprint:  33f9acb1d1132b67e38b5bd0b2c35123f5b2032a84f8a034be6604fc338815f1Signer key ID:     cc911e1df79b8b7b97229eb8c163c1405b581680af2cb940386f74437c7aa524Trusted via:       trusted key IDChecks:  1. Signing key is trusted (registration sheet or previous pack)   PASS     key cc911e1df79b8b7b97229eb8c163c1405b581680af2cb940386f74437c7aa524, trusted via trusted key ID  2. Manifest signature (DSSE, Ed25519) is valid                    PASS     Ed25519 signature over the manifest is valid  3. Every file matches its SHA-256 in the manifest                 FAIL     inventory.csv has SHA-256 00951cdee49cd0043f6c0b330b264e169f5145a4427582bbd913781b10a6e2b0, manifest says d1a167f91c009a0ede446cb27fd4b7f46653c20f11327be06d0949fdefa65532  4. Checkpoint signature is valid and matches the manifest         SKIPPED  5. Every entry has a valid inclusion proof to the checkpoint      SKIPPED  6. History is consistent with earlier checkpoints                 SKIPPED  7. Recomputed totals match the manifest counts                    SKIPPED[exit 4]

Check 3 names the file and both hashes. The checks after it are SKIPPED, because nothing in a pack that fails check 3 can be relied on. Exit code 4.

The wrong key fails at check 1, before anything else is trusted:

appliance verify -trust 0000000000000000000000000000000000000000000000000000000000000000 pack.zipEVIDENCE PACK VERIFICATIONResult:            UNKNOWN SIGNERReason:            manifest signed by key cc911e1df79b8b7b97229eb8c163c1405b581680af2cb940386f74437c7aa524, which is not a trusted key and has no valid handoff from oneVerified at:       2026-10-24T09:05:24ZChecks:  1. Signing key is trusted (registration sheet or previous pack)   FAIL     manifest signed by key cc911e1df79b8b7b97229eb8c163c1405b581680af2cb940386f74437c7aa524, which is not a trusted key and has no valid handoff from one  2. Manifest signature (DSSE, Ed25519) is valid                    SKIPPED  3. Every file matches its SHA-256 in the manifest                 SKIPPED  4. Checkpoint signature is valid and matches the manifest         SKIPPED  5. Every entry has a valid inclusion proof to the checkpoint      SKIPPED  6. History is consistent with earlier checkpoints                 SKIPPED  7. Recomputed totals match the manifest counts                    SKIPPED[exit 3]

At the next exam, verify the new pack against the previous one. -prev verifies the previous pack first, then trusts its key and uses its checkpoint to check this pack’s history:

appliance verify -prev pack.zip -trust cc911e1df79b8b7b97229eb8c163c1405b581680af2cb940386f74437c7aa524 pack-week2.zipPrevious pack pack.zip: PASS, fingerprint 33f9acb1d1132b67e38b5bd0b2c35123f5b2032a84f8a034be6604fc338815f1EVIDENCE PACK VERIFICATIONResult:            PASSVerified at:       2026-10-24T09:05:24ZPack fingerprint:  64b1a70c850fe8f630ac24e249799fcc1afa1a8b5859007f97bdfbe4f9ad77cbSigner key ID:     cc911e1df79b8b7b97229eb8c163c1405b581680af2cb940386f74437c7aa524Trusted via:       trusted key IDAppliance:         DEV01 (version dev)Build digest:      67440c787f3f4a937137e06b54d84cabb5c6ff019e4034733f90e2dd1fd31983Period:            2026-07-26T04:00:00Z to 2026-10-25T04:00:00ZLog:               gigidlabs.com/appliance/DEV01, size 264Log root:          qUGW5l91GHGFMUo6h0GzK7S62Iq7wlw1l5j9rnCLctw=Entries:           264 (seq 0 to 263, 2026-10-24T08:50:26Z to 2026-10-24T09:05:00Z)Decisions:         34Reviews:           1Exceptions:        6Devices:           approved 28, not_approved 6Coverage:          100.0% of source-days since install covered (covered 4)Assurance tier:    software_protectedDetection proofs:  coverageCrosswalk:         CIS Controls v8.1 / NIST CSF 2.0 / 12 CFR 30 App. B, 364 App. B, 748 App. A (2026-10)FIPS 140-3 mode:   offAnchored to:       CHECKPOINTS NOT ANCHOREDSeparation:        SINGLE-OPERATOR MODE (one person held Admin and Reviewer)Checks:  1. Signing key is trusted (registration sheet or previous pack)   PASS     key cc911e1df79b8b7b97229eb8c163c1405b581680af2cb940386f74437c7aa524, trusted via trusted key ID  2. Manifest signature (DSSE, Ed25519) is valid                    PASS     Ed25519 signature over the manifest is valid  3. Every file matches its SHA-256 in the manifest                 PASS     44 files match their manifest digests  4. Checkpoint signature is valid and matches the manifest         PASS     checkpoint for gigidlabs.com/appliance/DEV01 at size 264 is signed by a trusted key  5. Every entry has a valid inclusion proof to the checkpoint      PASS     264 entries (seq 0 to 263) and 35 cited entries are in the signed log  6. History is consistent with earlier checkpoints                 PASS     consistent with 1 independent checkpoint(s): size 181  7. Recomputed totals match the manifest counts                    PASS     entries, decisions, reviews, exceptions, devices and coverage all match[exit 0]

Check 6 now passes: this pack’s log is consistent with the previous pack’s checkpoint at size 181. A checkpoint from the bank’s SIEM works the same way, with -anchor checkpoint.txt (repeatable).

-json prints the same report as JSON, for a GRC tool, a SIEM or a script:

appliance verify -json -trust cc911e1df79b8b7b97229eb8c163c1405b581680af2cb940386f74437c7aa524 pack.zip{  "outcome": "PASS",  "verified_at": "2026-10-24T09:05:24.494726Z",  "pack_fingerprint": "33f9acb1d1132b67e38b5bd0b2c35123f5b2032a84f8a034be6604fc338815f1",  "signer_key_id": "cc911e1df79b8b7b97229eb8c163c1405b581680af2cb940386f74437c7aa524",  "trusted_via": "trusted key ID",  "checks": [    {      "step": 1,      "name": "Signing key is trusted (registration sheet or previous pack)",      "status": "pass",      "detail": "key cc911e1df79b8b7b97229eb8c163c1405b581680af2cb940386f74437c7aa524, trusted via trusted key ID"    },    {      "step": 2,      "name": "Manifest signature (DSSE, Ed25519) is valid",      "status": "pass",      "detail": "Ed25519 signature over the manifest is valid"    },    {      "step": 3,      "name": "Every file matches its SHA-256 in the manifest",      "status": "pass",      "detail": "18 files match their manifest digests"    },    {      "step": 4,      "name": "Checkpoint signature is valid and matches the manifest",      "status": "pass",      "detail": "checkpoint for gigidlabs.com/appliance/DEV01 at size 181 is signed by a trusted key"    },    {      "step": 5,      "name": "Every entry has a valid inclusion proof to the checkpoint",      "status": "pass",      "detail": "181 entries (seq 0 to 180) and 9 cited entries are in the signed log"    },    {      "step": 6,      "name": "History is consistent with earlier checkpoints",      "status": "not_checked",      "detail": "NOT CHECKED: no independent checkpoint (previous pack, SIEM or email) was supplied; the pack's own consistency proofs from 1 earlier pack checkpoint(s) are valid"    },    {      "step": 7,      "name": "Recomputed totals match the manifest counts",      "status": "pass",      "detail": "entries, decisions, reviews, exceptions, devices and coverage all match"    }  ],  "summary": {    "serial": "DEV01",    "version": "dev",    "build_digest": "67440c787f3f4a937137e06b54d84cabb5c6ff019e4034733f90e2dd1fd31983",    "generated_at": "2026-10-24T08:58:26Z",    "period_from": "2026-07-26T04:00:00Z",    "period_to": "2026-10-25T04:00:00Z",    "first_entry_time": "2026-10-24T08:50:26Z",    "last_entry_time": "2026-10-24T08:57:52Z",    "log_origin": "gigidlabs.com/appliance/DEV01",    "log_size": 181,    "log_root": "WQHNjvnRAxCGVYqbAizpIt2v6mD60suPkcokNrjkf0M=",    "entries_from": 0,    "entries_to": 181,    "entries": 181,    "decisions": 9,    "reviews": 0,    "exceptions": 1,    "devices": {      "approved": 8,      "needs_review": 25,      "not_approved": 1    },    "devices_by_tier": {      "switch": 34    },    "coverage": {      "covered": 4    },    "coverage_percent": "100.0%",    "assurance_tier": "software_protected",    "detection_proofs": [      "coverage"    ],    "crosswalk_version": "CIS Controls v8.1 / NIST CSF 2.0 / 12 CFR 30 App. B, 364 App. B, 748 App. A (2026-10)",    "fips_mode": false,    "fips_module": "latest",    "checkpoints_anchored": false,    "anchors": [],    "single_operator": true,    "notices": [      "checkpoints not anchored",      "single-operator mode"    ],    "discontinuities": [],    "history_checked": false  }}[exit 0]
  • A signed Rewind answer: appliance verify -trust <key ID> -answer answer.zip. The seven pack checks run, then step 8 replays the signed log and must reach the same answer byte for byte. See Rewind.
  • A signed board report: appliance report-verify -trust <key ID> board-report.zip. It verifies the embedded pack, then recomputes every figure. See Signed board report.
  • It fails closed: anything it cannot check is a failure or “not checked”, never a pass.
  • The ZIP container is parsed strictly and inflation is bounded to declared sizes, so a small file cannot expand into a large one.
  • Its parsers are fuzzed, and it shares only contract packages (model, jcs, textsafe) with the appliance.
  • Every check has a by-hand equivalent in Verify a pack by hand.

Every outcome and exit code is in What a verifier result means.