<p align="center">
<img src="https://cloudcdn.pro/hsh/v1/logos/hsh.svg" alt="hsh-cli logo" width="128" />
</p>
<h1 align="center">hsh-cli</h1>
<p align="center">
<strong>Command-line companion for <a href="../hsh/"><code>hsh</code></a> — hash, verify, rehash, inspect, calibrate.</strong>
</p>
<p align="center">
<a href="https://github.com/sebastienrousseau/hsh/actions"><img src="https://img.shields.io/github/actions/workflow/status/sebastienrousseau/hsh/ci.yml?style=for-the-badge&logo=github" alt="Build" /></a>
<a href="https://crates.io/crates/hsh-cli"><img src="https://img.shields.io/crates/v/hsh-cli.svg?style=for-the-badge&color=fc8d62&logo=rust" alt="Crates.io" /></a>
<a href="https://docs.rs/hsh-cli"><img src="https://img.shields.io/badge/docs.rs-hsh--cli-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" alt="Docs.rs" /></a>
</p>
---
## Contents
[Install](#install) · [Quick Start](#quick-start) · [Subcommands](#subcommands) · [Password resolution](#password-resolution) · [Exit codes](#exit-codes) · [JSON output](#json-output) · [Shell completions](#shell-completions) · [Examples](#examples) · [Security](#security)
---
## Install
```bash
cargo install hsh-cli
```
MSRV **1.85** stable. Edition 2024. Provides the `hsh` binary.
Packaging for Docker / Homebrew / Debian / Arch / Scoop is shipped under [`pkg/`](../../pkg/); each tagged release materialises ready-to-publish artefacts via [`release.yml`](../../.github/workflows/release.yml).
---
## Quick Start
```bash
# Hash a password (read from stdin)
# Verify
# → valid
# exit code 0
```
---
## Subcommands
| `hsh hash` | Hash a password → emit the storable PHC / MCF / envelope string |
| `hsh verify` | Verify a candidate password against a stored hash |
| `hsh rehash` | Verify + mint a fresh hash under the current policy (combined op) |
| `hsh inspect` | Pretty-print the algorithm + parameters of any stored hash |
| `hsh inspect-backend` | Show the effective crypto route for a preset (operator self-check) |
| `hsh calibrate` | Walk a parameter ladder; report the params closest to a wall-time target |
| `hsh completions` | Emit bash / zsh / fish / powershell / elvish completion scripts |
Every subcommand accepts `--json` for machine-readable output. `hash`, `verify`, `rehash`, and `inspect-backend` take `--policy {owasp,rfc9106,fips}` to switch the parameter ladder; `calibrate` takes `--algorithm` and `--target-ms` instead.
### `hsh hash`
```bash
hsh hash --algorithm argon2id --policy owasp
hsh hash --algorithm bcrypt --policy owasp --json
hsh hash --algorithm pbkdf2 --policy fips # errors: FIPS feature not built in
```
### `hsh verify`
```bash
hsh verify -H "$STORED"
# Reads password from stdin / $HSH_PASSWORD env / TTY prompt.
# Plain output:
# valid (exit 0)
# needs_rehash: true (when policy drifted)
# rehashed: $argon2id$... (the fresh hash to persist)
# Or:
# invalid (exit 1)
```
### `hsh rehash`
```bash
hsh rehash -H "$STORED" --policy rfc9106
# Verifies, then unconditionally mints a fresh hash under the
# current policy. Useful for batch migration scripts.
```
### `hsh inspect`
```bash
hsh inspect '$argon2id$v=19$m=19456,t=2,p=1$YWJjZGVmZ2hpamtsbW5vcA$dGVzdA'
# → format: phc
# algorithm: argon2id
# params[1]: v=19
# params[2]: m=19456,t=2,p=1
# segment[3]: YWJjZGVmZ2hpamtsbW5vcA
# hash_b64: dGVzdA
```
### `hsh inspect-backend`
Operator self-check: confirms the binary's effective crypto route for a
given preset before traffic touches it. Surfaces the backend
(`Native` / `Fips140Required`), whether this build can satisfy a FIPS
requirement (`fips_available_in_build`), the primary algorithm, whether
the `pepper` feature was compiled in, plus build provenance (hsh-cli
version, rustc, target triple, profile).
```bash
hsh --json inspect-backend --policy fips
# → {
# "backend": "Fips140Required",
# "fips_available_in_build": false,
# "primary_algorithm": "Pbkdf2",
# "readiness": "unsatisfied (build cannot provide a FIPS-validated route)",
# "preset": "fips_140_pbkdf2",
# "rustc": "rustc 1.95.0 (…)",
# "target_triple": "x86_64-unknown-linux-gnu",
# …
# }
```
Gate a deploy with `jq`:
```bash
hsh --json inspect-backend --policy "$DESIRED" \
| jq -e '.readiness == "satisfied"' >/dev/null \
See [`doc/OPERATIONS.md`](../../doc/OPERATIONS.md) for the full
pre-deployment workflow.
### `hsh calibrate`
```bash
hsh calibrate --algorithm argon2id --target-ms 500
# Walks m_cost ∈ {4096, 8192, 19456, 32768, 65536, 131072},
# reports the params that hit closest to 500 ms.
# JSON mode (--json) also emits a `ladder` array with every candidate
# and a `runner` block with host_os / arch / target_triple / profile /
# rustc / hsh_cli_version so sizing decisions are tied to the host
# that produced them.
```
### `hsh completions`
```bash
hsh completions bash > /etc/bash_completion.d/hsh
hsh completions zsh > ~/.zsh/functions/_hsh
hsh completions fish > ~/.config/fish/completions/hsh.fish
```
---
## Password resolution
`hsh-cli` resolves the password in this order (and **never** accepts it on the command line):
1. **`--password <value>` flag** — discouraged; documented as insecure (leaves password in shell history).
2. **`$HSH_PASSWORD` env var** — for batch scripts.
3. **TTY prompt with no echo** — when stdin is a terminal.
4. **First line of stdin** — for pipelines.
The same priority applies to `--stored` / `$HSH_STORED` for hash inputs.
---
## Exit codes
| `0` | Success (verify match, hash produced, completions emitted, etc.) |
| `1` | Verify mismatch (wrong password) — only `verify` and `rehash` |
| `2` | Error (malformed input, missing flag, policy contradiction) |
These are stable per [`doc/API-STABILITY.md`](../../doc/API-STABILITY.md).
---
## JSON output
Every subcommand accepts `--json`:
```bash
# "stored": "$scrypt$ln=17,r=8,p=1$<salt>$<hash>",
# "algorithm": "Scrypt"
# }
```
The JSON schema is stable per the stability contract — additive changes only.
---
## Shell completions
`hsh-cli` ships completions for **bash, zsh, fish, powershell, elvish** via the `completions` subcommand. The Arch (`PKGBUILD`) and Homebrew templates wire these into standard locations automatically — see [`pkg/`](../../pkg/).
---
## Examples
See [`crates/hsh-cli/examples/`](examples/) for the runnable demo:
- `library_shape.rs` — programmatic walk-through of what the `hash`
and `verify` subcommands do under the hood, useful for embedding the
same flow in your own binary rather than shelling out.
Run with `cargo run -p hsh-cli --example library_shape`.
---
## Security
- **Passwords are never on argv.** The `--password` flag exists but is documented insecure.
- **Verify exits 1 on mismatch**, 2 on error — no ambiguity for shell-script callers.
- **TTY prompts use `rpassword`** (no echo).
- **No telemetry**, no network calls, no log files.
See [`SECURITY.md`](../../SECURITY.md) for the vulnerability reporting policy.
---
## License
Dual-licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0) or [MIT](https://opensource.org/licenses/MIT), at your option.
<p align="right"><a href="#hsh-cli">Back to top</a></p>