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-cli
Or download a prebuilt binary from GitHub Releases.
Verify the installation:
h2h --version
h2h 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.yaml
Exit 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 tap
h2h 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-project
h2h 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.yaml
Lint 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.yaml
h2h 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.yaml
h2h 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.yaml
Checks 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 deactivate
h2h 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.sig
h2h 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 ./keys
Common 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.yaml
Running 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 tap
Policy 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.yaml
Emergency 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