SDK reference /CLI — heso

CLI — heso

Two command-line tools. The heso CLI ships with the Python package and handles scaffolding and local verify. The standalone heso-verify-cliis a Rust binary that verifies evidence bundles offline, with no HESO install on the verifier’s machine.

Use the heso CLI to set a project up and check receipts during development. Use heso-verify-cli when someone outside your stack needs to confirm a receipt bundle is genuine. Both run the same offline verify path as the SDK, so verdicts match everywhere.

Common tasks

What this proves

A receipt proves you authorized an action under your policy. It does not prove the action succeeded downstream.

The heso CLI

Installed with pip install heso (Python 3.10+). It bundles the Rust core as the in-process heso._core wheel, so scaffolding, minting, and verify all run in your process with no subprocess. For the full Python surface — heso.init(), the decorators, and the proxy — see the Python SDK reference.

heso init

heso initcommand

Scaffold a HESO project: write heso.toml and the bootstrap module, gitignore the local data directory, and mint the operator identity in-process.

bash
heso init [dir] [--require-passphrase]

Parameters

dirpath
The directory to scaffold. Defaults to the current working directory. Created if it does not exist.
--require-passphraseflag
Strict custody: do not auto-generate a dev passphrase. The mint then fails unless HESO_KEY_PASSPHRASE is set. Implied by HESO_ENV=production and the HESO_REQUIRE_PASSPHRASE env var.

Example

bash
# scaffold the current directory
heso init

# or scaffold a named project directory
heso init my-agent

What it writes:

  • heso.toml — a starter policy that allows model and tool calls and gates large payments and deletes to a human. Edit it to fit your controls; see writing policy.
  • heso_bootstrap.py — a one-line module that calls heso.init(). See the bootstrap module below.
  • A .gitignore entry for the local data directory, which holds the minted key, the audit log, and the outbox queue. None of it is ever committed.
  • A dev key passphrase at heso-local-data/DEV-ONLY.passphrase (mode 0600), unless one exists or strict mode is on — see the dev key passphrase below.

A scaffolded project:

my-agent/bash
my-agent/
  heso_bootstrap.py     # import heso; heso.init()
  heso.toml             # starter policy, written by heso init
  .gitignore            # ignores the local data dir (minted key, audit log, outbox)
Idempotent

heso init is safe to re-run. An existing key, heso.toml, and dev passphrase file are left as-is, so you will not overwrite a minted identity or a policy you have edited.

heso demo

heso democommand

Init the project if needed, mint one allowed and one redacted sample receipt through the real engine, and verify both offline.

bash
heso demo [dir]

Parameters

dirpath
The project directory. Defaults to the current working directory. If it is not yet scaffolded, heso demo runs heso init first.

Example

bash
# init if needed, then mint one allowed + one redacted receipt and verify both
heso demo

The two receipts are appended to heso-local-data/receipts.jsonl and verified in place, each reported with its PascalCase verdict and trust level:

bash
minting your first receipts through the engine:
  allow     7f3c91ab…  ->  Valid (L0)
  redacted  2a8e04dd…  ->  Valid (L0)

  receipts written to /path/to/your-agent/heso-local-data/receipts.jsonl
  verify either yourself, offline:
      heso verify 7f3c91ab…

heso verify

heso verifycommand

Verify a single stored receipt or receipt file offline and print the verdict and trust level. Exit 0 only on Valid, 1 otherwise.

bash
heso verify <path|hash>

Parameters

path | hashstring
A path to a receipt .json file, or an action_hash (full or a unique prefix) looked up in heso-local-data/receipts.jsonl. A prefix that matches more than one stored receipt is an error.

Example

bash
# by action_hash (full or a unique prefix) from the local store…
heso verify 7f3c91ab

# …or a receipt JSON file straight off disk
heso verify ./receipt.json
bash
  action 7f3c91ab…
  Valid (L0)
  (verified offline — re-ran BLAKE3 + Ed25519 locally, zero network)

The verdict is the engine’s own PascalCase result — Valid, HashMismatch, WrongAlgorithm, and so on — followed by the trust level (L0 operator-signed, L1 human co-signed) for a valid receipt. The command exits 0 only on a Valid verdict and 1 on anything else, so it drops straight into a CI gate.

heso show

heso showcommand

Pretty-print a stored receipt's full signed JSON, looked up by action_hash (or a path to a receipt file).

bash
heso show <hash>

Parameters

hashstring
The receipt’s action_hash (full or a unique prefix), or a path to a receipt JSON file. Resolved the same way as heso verify.

Example

bash
heso show 7f3c91ab

It prints the receipt indented and key-sorted — the same signed envelope documented field by field in the receipt schema.

The bootstrap module

heso init writes heso_bootstrap.py. It is one call: heso.init() resolves and installs your config, which every decorator and the proxy read from.

heso_bootstrap.pypython
import heso

heso.init()

Import it once at process start, at the top of your entrypoint, so the config is in place before the first gated call:

main.pypython
# import the bootstrap once, at the very top of your entrypoint
import heso_bootstrap  # noqa: F401

from my_agent import run
run()

The dev key passphrase

The operator key is encrypted at rest, and every key loader reads its passphrase from HESO_KEY_PASSPHRASE. To keep a fresh machine from hard-failing at heso init, when that variable is unset the CLI auto-generates a dev passphrase into heso-local-data/DEV-ONLY.passphrase and heso.init() loads it back, so the in-process lifecycle works with zero setup.

Labeled dev mode, not weakened custody

The dev passphrase file sits next to the key it unlocks, so it adds no real protection. An explicit HESO_KEY_PASSPHRASE always wins and the dev file is never consulted. For production, set a real HESO_KEY_PASSPHRASE from your secrets manager and delete the dev file. Running under HESO_ENV=production hard-blocks the dev file; heso init --require-passphrase opts into that strict posture in any environment.

bash
# production: set a real passphrase and refuse the dev file
export HESO_KEY_PASSPHRASE="…from your secrets manager…"
export HESO_ENV=production   # hard-blocks the DEV-ONLY.passphrase fallback

# or opt into strict custody in any environment
heso init --require-passphrase

heso-verify-cli

A standalone Rust binary that verifies an evidence bundle offline with no HESO install on the machine running it. It reads a chained receipts.jsonland the pinned operator public key, runs the same verify path as the SDK, and reports a verdict with a Unix exit code. It is the same verifier an offline-verifiable bundle’s VERIFY.sh invokes — see offline verification.

heso-verify-clicommand

Verify a receipts bundle against a pinned operator public key. Add --json for a compact machine-readable result.

bash
heso-verify-cli [--json] <receipts.jsonl> <public_key_file>

Parameters

--jsonflag
Emit a compact JSON result instead of the human-readable line.
receipts.jsonlpath
The chained receipts file to verify.
public_key_filepath
The pinned operator public key the bundle is checked against.

Example

bash
# verify a receipt bundle offline, no heso install needed
heso-verify-cli receipts.jsonl operator.pub

# machine-readable verdict
heso-verify-cli --json receipts.jsonl operator.pub

Exit codes:

CodeMeaning
0VALID
1INVALID
2WRONG ALG/HASH
64USAGE

With --json it emits a compact JSON result you can parse in a pipeline:

json
{"status":"VALID","exit":0,"count":2}

Next steps