CLI Reference
h2h ("hush to hush") is the official CLI for HushSpec policy management. It provides 11 subcommands covering validation, testing, formatting, auditing, signing, and emergency controls.
Installation#
Install from crates.io with Cargo:
cargo install hushspec-cliOr download a prebuilt binary from GitHub Releases.
Verify the installation:
h2h --versionh2h validate#
Validate policy files against the HushSpec schema. Checks YAML syntax, structural validation, and optionally resolves extends references.
h2h validate <files...> [--format text|json] [--strict]Flags#
--format, -f- Output format:text(default) orjson--strict- Also verify thatextendsreferences resolve correctly
Example#
# Validate a single policy
h2h validate policy.yaml
# Strict mode with JSON output
h2h validate --strict --format json policy.yamlExit codes: 0 = all valid, 1 = validation errors, 2 = file not found.
h2h test#
Run evaluation test suites against policies. Test fixtures define expected decisions for specific actions and verify the policy produces them.
h2h test [files...] [--fixtures <dir>] [--policy <file>] [--format text|tap|json]Flags#
--fixtures- Directory containing.test.yamlfixture files--policy, -p- Policy file to test against (overrides the policy embedded in fixtures)--format, -f- Output format:text(default),tap, orjson
Example#
# Run all fixtures in a directory
h2h test --fixtures ./tests/
# Test a specific policy against fixtures
h2h test --policy policy.yaml --fixtures ./tests/
# TAP output for CI integration
h2h test --fixtures ./tests/ --format taph2h init#
Scaffold a new policy project. Creates a .hushspec/ directory with a policy file and starter test fixtures.
h2h init [--preset <preset>] [--dir <path>]Flags#
--preset- Security preset:default,strict, orpermissive--dir- Directory to create.hushspec/in (defaults to current directory)
Example#
# Scaffold with the default preset
h2h init
# Scaffold with strict preset in a specific directory
h2h init --preset strict --dir ./my-projecth2h lint#
Run static analysis and best-practice checks on policy files. Detects empty rule blocks, overlapping patterns, shadowed exceptions, overly broad wildcards, regex complexity, and more.
h2h lint <files...> [--format text|json] [--fail-on-warnings]Flags#
--format, -f- Output format:text(default) orjson--fail-on-warnings- Exit1if any warnings are reported (not just errors)
Example#
# Lint a policy
h2h lint policy.yaml
# Strict linting in CI (fail on warnings)
h2h lint --fail-on-warnings policy.yamlLint codes: L001 empty rule block, L002 overlapping patterns, L003 shadowed exception, L004 overly broad wildcard, L005 empty blocklist with default allow, L006 regex complexity, L007 disabled rule, L008 duplicate pattern, L009 missing secret patterns, L010 unreachable allow.
h2h diff#
Compare two policies and show effective decision changes. Generates probes from both policies and evaluates them to detect tightened, relaxed, escalated, or demoted decisions.
h2h diff <old> <new> [--format text|json]Flags#
--format, -f- Output format:text(default) orjson
Example#
# Compare two policy versions
h2h diff policy-v1.yaml policy-v2.yaml
# JSON output for programmatic analysis
h2h diff --format json old.yaml new.yamlh2h fmt#
Format policy files into canonical form. Sorts list entries, normalizes field ordering, and ensures consistent quoting.
h2h fmt <files...> [--check] [--diff] [--format text|json]Flags#
--check- Check formatting without modifying files (exit1if changes needed)--diff- Show what would change without modifying files--format, -f- Output format:text(default) orjson
Example#
# Format in place
h2h fmt policy.yaml
# Check formatting in CI
h2h fmt --check policy.yaml
# Preview changes without writing
h2h fmt --diff policy.yamlh2h audit#
Display governance metadata and run advisory checks. Inspects policy metadata fields (author, approver, classification, lifecycle state, expiry) and reports their presence. Audit is advisory - it always exits 0.
h2h audit <file> [--format text|json]Flags#
--format, -f- Output format:text(default) orjson
Example#
# Audit a policy
h2h audit policy.yaml
# Machine-readable audit report
h2h audit --format json policy.yamlChecks performed: has author, has approver, has approval date, classification set, lifecycle state set, policy version set, expiry date set, restricted approval check.
h2h panic#
Manage emergency panic mode (deny-all kill switch). Creates or removes a sentinel file that causes all evaluate() calls to return deny.
h2h panic activate [--sentinel <path>]
h2h panic deactivate [--sentinel <path>]
h2h panic status [--sentinel <path>]Subcommands#
activate- Create the sentinel file, activating deny-all modedeactivate- Remove the sentinel file, restoring normal evaluationstatus- Check whether panic mode is currently active
Flags#
--sentinel- Path to the sentinel file (defaults to.hushspec_panicin the current directory)
Example#
# Activate panic mode
h2h panic activate --sentinel /tmp/hushspec.panic
# Check status
h2h panic status
# Deactivate
h2h panic deactivateh2h sign#
Sign a policy file with an Ed25519 private key. Produces a detached .sig file containing the signature, content hash, key ID, and timestamp.
h2h sign <policy> --key <keyfile> [--key-id <id>] [--signer <identity>] [--output <path>]Flags#
--key, -k- Path to the Ed25519 private key file--key-id- Key identifier (defaults to a truncated hash of the public key)--signer- Human-readable signer identity (e.g. email address)--output, -o- Output path for the.sigfile (defaults to<policy>.sig)
Example#
# Sign a policy
h2h sign policy.yaml --key h2h.key
# Sign with signer identity
h2h sign policy.yaml --key h2h.key --signer "ops@example.com"h2h verify#
Verify a policy file's detached Ed25519 signature. Checks the content hash and cryptographic signature against the provided public key.
h2h verify <policy> --key <pubkey> [--sig <sigfile>]Flags#
--key, -k- Path to the Ed25519 public key file--sig, -s- Path to the detached.sigfile (defaults to<policy>.sig)
Example#
# Verify a signed policy
h2h verify policy.yaml --key h2h.pub
# Verify with explicit signature file
h2h verify policy.yaml --key h2h.pub --sig policy.yaml.sigh2h keygen#
Generate a new Ed25519 keypair for policy signing. Creates h2h.key (private, mode 0600) and h2h.pub (public) in the output directory.
h2h keygen [--output-dir <dir>]Flags#
--output-dir- Directory to write key files to (defaults to the current directory)
Example#
# Generate keys in current directory
h2h keygen
# Generate keys in a specific directory
h2h keygen --output-dir ./keysCommon Workflows#
Validating and linting before commit#
Run both validate and lint as a pre-commit check to catch schema errors and policy anti-patterns early:
h2h validate --strict .hushspec/policy.yaml && \
h2h lint --fail-on-warnings .hushspec/policy.yaml && \
h2h fmt --check .hushspec/policy.yamlRunning conformance tests#
Use test fixtures to verify your policy produces the expected decisions:
# Initialize a new project with starter tests
h2h init --preset default
# Run the tests
h2h test --fixtures .hushspec/tests/
# Run tests with TAP output for CI
h2h test --fixtures .hushspec/tests/ --format tapPolicy diffing for PR review#
Compare the base branch policy against the PR branch to understand how decisions change:
# Diff the policies
h2h diff main:.hushspec/policy.yaml pr:.hushspec/policy.yaml
# JSON output for automated review comments
h2h diff --format json old-policy.yaml new-policy.yamlEmergency panic mode#
When you need to immediately deny all agent actions:
# Activate: all evaluate() calls now return deny
h2h panic activate --sentinel /var/run/hushspec.panic
# Check current status
h2h panic status --sentinel /var/run/hushspec.panic
# Deactivate: resume normal policy evaluation
h2h panic deactivate --sentinel /var/run/hushspec.panic