Ankos
CLI Reference

ankos verify-integrity

Independently verify the integrity of an evidence package against its SHA-256 manifest. Catches corruption, tampering, or accidental modification.

ankos verify-integrity recomputes the SHA-256 hash of every file in an evidence directory and compares it against the hash recorded in manifest.json. Use it before handing a package to your QSA, after copying a package between machines, or any time you want to prove the bytes haven't changed since the scan.

Formerly ankos verify — that shorter name still works as a deprecated alias, so existing scripts and pipelines don't break.

Synopsis

ankos verify-integrity <evidence-dir>

Quick start

# Verify a fresh scan
ankos verify-integrity ankos-evidence-20260526-153045/

Output (success):

Verifying 54 evidence files in ankos-evidence-20260526-153045/

  ✓ acm.json
  ✓ apigateway.json
  ✓ athena.json
  ... (one ✓ per file)
  ✓ evidence.json
  ✓ vpc.json

✓ All 54 evidence files verified — no unexpected files

verify-integrity checks four things and exits non-zero on any of them:

  • Hash mismatch — a file's bytes no longer match the manifest.
  • Size mismatch — a file's byte length differs from the recorded size_bytes.
  • Missing file — a file listed in the manifest isn't on disk.
  • Unexpected file — a *.json file on disk that the manifest does not list (a planted/fabricated evidence file). Without this check, dropping a fake collector file next to real evidence would still pass.

Why verify

Each ankos scan writes a manifest.json listing every output file — including the aggregate evidence.json, which carries the authoritative account ID, regions, and provenance — with its SHA-256 hash and size at the moment of writing. The manifest protects against:

  • Accidental edits to the JSON evidence after the scan (a teammate opens a file in an editor and saves it with different whitespace, changing the byte stream)
  • Corruption in transit (the package was copied to a USB stick that flipped a bit, or downloaded from an upload that silently truncated)
  • Substitution (one evidence file swapped for a fabricated version before handing to the QSA)
  • Planted evidence (an extra file added that the scan never produced)

The hash is a standard SHA-256 over the file bytes. You don't need Ankos to verify it — shasum -a 256 <file> produces the same value. That's the point: Ankos can be removed from the trust path entirely.

The manifest checksum sidecar

The scan also writes a manifest.sha256 sidecar — the SHA-256 of manifest.json itself. The same value is printed at scan time, giving your QSA one out-of-band number to confirm the manifest wasn't swapped wholesale. verify-integrity checks the sidecar automatically when present.

Verifying without the CLI

If you don't have the CLI installed (or want to prove the verification yourself), use jq + shasum:

cd ankos-evidence-20260526-153045/
jq -r '.hashes | to_entries[] | "\(.value)  \(.key)"' manifest.json \
  | shasum -a 256 -c -

Every line should report OK. Any FAILED indicates the file's bytes no longer match the recorded hash.

This is the recipe printed in the README of every Ankos evidence package — your QSA can run it without installing anything beyond standard Unix tools.

What's in the manifest

The manifest.json file is a single JSON object:

{
  "algorithm": "sha256",
  "scan_id": "a3f8e2c4-7b91-4d15-8e2a-f0c9b3d56e8a",
  "account_id": "123456789012",
  "regions_scanned": ["us-east-1"],
  "collectors_run": ["iam", "vpc", "kms", "..."],
  "ankos_version": "1.0.0",
  "commit": "9f2a1c0",
  "build_date": "2026-06-04",
  "generated_at": "2026-05-26T15:30:45Z",
  "duration_seconds": 7.229,
  "hashes": {
    "iam.json": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    "vpc.json": "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e",
    "evidence.json": "...",
    "kms.json": "..."
  },
  "files": [
    { "filename": "iam.json", "sha256": "e3b0c4...", "size_bytes": 4823 }
  ]
}

The hashes field (and the files array, which adds size_bytes) is the authoritative source — the order doesn't matter, only the (filename → hash) mapping. commit and build_date record exactly which CLI build produced the scan.

See Scan output for the rest of the evidence package shape.

Exit codes

CodeMeaning
0All files match their manifest hash + size, and no unexpected files
1Could not read or parse the manifest, or hash algorithm not supported
2One or more files failed verification