Build: 1.0.37 (230f54ff82)
Generated by hasp docs markdown. Every help topic is rendered
verbatim inside a fenced code block so leading whitespace and
table characters survive the markdown round-trip.
hasp keeps secrets in one local vault and hands them to your apps, agents, and repo-scoped commands without leaving raw values in source control.
Core concepts
vault encrypted local store of named secrets under HASP_HOME
repo a project root you bind so commands run inside it can pull secrets
target a repo-declared delivery subset; never an authority by itself
agent a connected app or coding agent that gets brokered access
grant short-lived, scoped permission to deliver a secret to one run
Start here
hasp setup
hasp secret add
hasp agent connect <profile> --project-root .
hasp proof --secret <name-or-alias>
For lower-level vocabulary (operator/integrator surface) see: hasp help internals
Daily commands
setup guided machine, repo, and agent setup
doctor diagnose daemon, vault, binding, hooks, and audit state
secret add, update, show/reveal/copy, expose, and hide vault items
app connect an app profile and run it with managed secrets
agent connect an agent once and let it pull through HASP
template alias for value-free project manifest targets
run run a repo-scoped command through the broker
inject run a command with env or file refs resolved by HASP
proof run the brokered first-proof check (replaces the long quickstart one-liner)
Help topics
hasp help setup
hasp help secret
hasp help secret add
hasp help app
hasp help app connect
hasp help agent
hasp help agent connect
hasp help run
hasp help inject
hasp help doctor
Advanced and automation
hasp help internals
hasp help check-repo
hasp help write-env
hasp help completion
hasp help docs
hasp help upgrade
hasp help telemetry
Output
--json machine-readable output on stdout for status, list, and mutation commands.
errors are emitted as a single JSON envelope on stderr with stable
error codes (E_USER_INPUT, E_PERMISSION, E_DAEMON_UNREACHABLE, ...).
commands that have no JSON form ignore the flag rather than erroring.
See: hasp help exit-codes for the bucket table.
hasp init
Create the local encrypted vault under HASP_HOME.
Use this once per machine or once per HASP_HOME.
Flags
--json emit machine-readable result on stdout
Examples
hasp init
hasp init --json
hasp setup
Guide a user through machine setup. This command can choose the HASP home,
optionally bind one repo, optionally skip agent setup, and in interactive use
continue into adding secrets or connecting an app.
Use setup when you want one guided flow. Use the lower-level commands when you
already know the exact state you want.
Master password policy
Newly created vaults require a master password of at least 12 characters
with more than one distinct character. Pass --skip-password-policy if your
organisation enforces its own policy upstream (corporate password manager,
FIDO-derived secret, etc.).
Flags
--non-interactive run without prompts; all required values must
be supplied via flags or environment variables
--json emit machine-readable output on stdout
--hasp-home <path> override HASP_HOME for this invocation
--project-root <path> bind a repo at this path during setup
(alias: --repo, deprecated)
--master-password-env <var> read master password from this env var name
--master-password-stdin read master password from stdin
--import <path> import secrets from this file during setup
--import-format <fmt> format for --import: auto (default), env, json
--bind-imports bind imported secrets to the repo
--default-policy <policy> default policy to apply to the vault
--skip-password-policy skip the minimum-entropy password check
--agent <name> agent profile to connect during setup
--bind-item <name> bind a vault item to the repo (repeatable)
--alias <name=ref> add a repo alias mapping (repeatable)
--auto-protect-repos <val> always|never|ask: auto-protect new repos
--install-hooks <val> always|never|ask: install git hooks in repo
--enable-convenience-unlock <val>
always|never|ask: enable keychain unlock
--overwrite-existing-config <val>
always|never|ask: overwrite existing config
--telemetry <val> always|never|on|off|ask: optional CLI telemetry;
default is never in non-interactive setup
Examples
hasp setup
hasp setup --non-interactive --hasp-home ~/.hasp --project-root . --agent claude-code --telemetry=never
hasp bootstrap
Configure a repo and an agent profile in one operator-focused flow. Bootstrap
exists for repo-first workflows. The newer app- and agent-first path is usually:
hasp secret add
hasp agent connect claude-code --project-root .
Subcommands
generic write a generic agent profile for the current repo
doctor diagnose a previously bootstrapped repo/profile pair
Master password policy
When bootstrap creates a new vault from HASP_MASTER_PASSWORD it enforces a
minimum-length and basic-entropy check (at least 12 characters and more
than one distinct character). Pass --skip-password-policy when an upstream
policy already governs the password.
Flags
--json emit machine-readable result on stdout
--alias <alias=item> add a repo alias mapping (repeatable)
--bind-item <name> bind a vault item to the repo (repeatable)
--bind-imports bind imported secrets to the repo binding
--default-policy <policy> default policy: auto|session|access
--hooks install git hooks in the repo (default: true)
--verify run a post-bootstrap verification pass
(default: true)
Examples
hasp bootstrap --profile claude-code --project-root .
hasp bootstrap generic --project-root .
hasp bootstrap doctor --profile claude-code --project-root .
hasp doctor
Diagnose local HASP health without exposing secrets or reconnaissance-heavy
details in JSON mode.
JSON output is intentionally allowlisted to daemon, vault, binding, hooks,
audit-degraded, version-number, and fixes_* fields.
Repair
--fix attempt to repair common breakage:
- tighten HASP_HOME perms to 0700
- remove stale socket files (regular files ending in .sock; the
live daemon's socket is a unix domain socket, not a regular
file, so this never touches a working daemon)
Each repair is recorded under fixes_attempted / fixes_succeeded /
fixes_failed so the operator can see what was touched.
Flags
--project-root <path> repo root to include in the binding health check
(default: current directory)
--target <id> run a scoped integration doctor for one target
--profile <id> limit a scoped integration doctor to one profile
--json emit machine-readable result on stdout
--fix attempt to repair common breakage (see above)
Examples
hasp doctor
hasp doctor --json
hasp doctor --fix
hasp doctor --target shell-hook --json
hasp import
Import secrets from a .env file or a JSON credential file. You can also rescue
pasted values or shell-style `export FOO=bar` snippets by piping them on
stdin with `hasp import --format env -`; HASP strips the `export `
prefix so pasted shell-export lines land in the vault without creating a repo-
visible env file. Add `--preview` first to see what the import would
change before it commits.
Use import when you already have secrets on disk, in the clipboard, or in an
ambient shell session and want to move them into the vault without leaving them
in `.env` or shell profiles. Use secret add when you want to enter values
directly.
Flags
--json emit machine-readable result on stdout
--name <name> store all imported values under this single name
(only valid when the source has exactly one entry)
--project-root <p> repo root to bind imported secrets to (requires --bind)
--bind expose imported secrets to the specified repo
--preview show what would be imported without committing
--format <fmt> input format: auto (default), env, json
Examples
hasp import .env
hasp import service-account.json
hasp import --project-root . --bind .env
printf 'export API_TOKEN=abc123\n' | hasp import --preview --format env -
printf 'export API_TOKEN=abc123\n' | hasp import --format env -
hasp set (DEPRECATED)
Add or replace one secret without an interactive prompt.
DEPRECATED: prefer 'hasp secret add --vault-only' (with --from-stdin for
non-interactive scripts). 'hasp set' still works for one release.
Prefer --value-stdin over --value: --value places the plaintext on argv where
ps, shell history, and accounting logs can see it. --value still works but
emits a warning. --value and --value-stdin are mutually exclusive.
Flags
--name <name> secret name (required)
--kind <kv|file> secret kind (default: kv)
--value <val> plaintext value on argv (UNSAFE; emits a warning)
--value-stdin read plaintext value from stdin
--from-file <path> read value from a file
--json emit machine-readable result on stdout
Examples
printf 'sk-123' | hasp secret add --vault-only --from-stdin OPENAI_API_KEY
hasp set --name CERT_FILE --kind file --from-file cert.pem
hasp set --name OPENAI_API_KEY --value sk-123 # works, warns about argv
hasp capture (DEPRECATED)
Save a value into the vault and optionally bind it to a repo while you already
have a live broker session.
DEPRECATED: prefer 'hasp secret add' with --expose=always (or --vault-only).
'hasp capture' still works for one release.
Flags
--json emit machine-readable result on stdout
--kind <kv|file> secret kind (default: kv)
--from-file <path> read secret value from a file instead of argv
--session-token <token> use an existing broker session token
--grant-project <scope> project grant scope: once|session|window|<dur>
--grant-secret <scope> secret grant scope: once|session|window|<dur>
--grant-window <duration> maximum age for a grant (e.g. 15m)
--grant-write require a write grant for the capture
Examples
hasp capture --name api_token --value abc123
hasp capture --name api_token --value abc123 --project-root . --bind
hasp secret
Work with the one local vault. These commands do not create new vaults per repo
or per app.
Subcommands
add add one or more secrets
update replace existing secret values
rotate replace a value for incident response and revoke grants
delete remove secrets from the vault
show print secret metadata only (no value)
reveal print the secret value to stdout (opt-in)
copy copy the secret value to the clipboard (opt-in)
get legacy alias for show; --reveal/--copy still work
retrieve alias for secret get
list list secret names and metadata
search filter the inventory by a case-insensitive substring on the name
diff compare a candidate .env file against the vault by name only
expose bind a secret to a repo boundary and create a reference
hide remove one repo exposure for a secret
Common flags
--json emit machine-readable output on stdout (all subcommands that
produce structured output honour this flag)
Learn more
hasp help secret add
hasp help secret expose
hasp secret add
Add one or more secrets to the vault. In a repo, HASP can also expose the new
secret to that repo boundary, but only with explicit operator consent: in
interactive use HASP asks; in scripts you must pass --vault-only,
--expose=never, or --expose=always.
Use this as the main human path. Pass bare names; values are read from a hidden
prompt or from stdin via --from-stdin. NAME=VALUE on argv is rejected because
ps, shell history, and accounting logs can see it.
Flags
--json emit machine-readable result on stdout
--project-root <path> repo root to use for the expose step
--kind <kv|file> secret kind (default: kv)
--from-file <path> read secret value from a file (kv or file kind)
--from-stdin read secret value from stdin
--on-conflict <policy> collision policy: ask|skip|overwrite (default: ask)
--vault-only skip the bind step (alias for --expose=never)
--expose=ask prompt for the bind decision (default; errors in scripts)
--expose=always bind without prompting (script opt-in)
--expose=never don't bind even if the cwd is a repo
Examples
hasp secret add
hasp secret add OPENAI_API_KEY
hasp secret add --vault-only
hasp secret add --expose=always TOKEN
printf 'sk-123' | hasp secret add --from-stdin --expose=never OPENAI_API_KEY
hasp secret add --kind file --from-file cert.pem CERT_FILE
hasp secret update
Replace the value for one or more existing secrets.
Flags
--json emit machine-readable result on stdout
Examples
hasp secret update OPENAI_API_KEY
hasp secret update
hasp secret rotate
Replace a local HASP secret value for incident response and invalidate active
grants for that local item. Provider-side credential rotation remains the
operator's responsibility.
The new value comes from a hidden prompt (or piped stdin); NAME=VALUE on argv
is rejected because ps, shell history, and accounting logs can see it.
Flags
--json emit machine-readable result on stdout
Examples
hasp secret rotate OPENAI_API_KEY
hasp secret rotate --json OPENAI_API_KEY
printf 'new-local-value' | hasp secret rotate OPENAI_API_KEY
hasp secret delete
Delete one or more secrets from the vault. HASP asks for confirmation unless
you pass --yes.
Flags
--json emit machine-readable result on stdout
--yes skip the confirmation prompt
Examples
hasp secret delete OPENAI_API_KEY
hasp secret delete --yes OPENAI_API_KEY
hasp secret delete --json OPENAI_API_KEY
hasp secret get
Retrieve a secret value only when you explicitly reveal or copy it. By default
this command shows secret metadata. Agents should use named refs with the MCP
broker path instead of raw get or reveal.
This verb stays for back-compat. Prefer the intent-named form:
hasp secret show metadata only
hasp secret reveal value to stdout
hasp secret copy value to the clipboard
When agent-safe mode is active, HASP blocks --reveal and --copy unless the
operator first grants one-time plaintext access with hasp session
grant-plaintext.
Examples
hasp secret get OPENAI_API_KEY
hasp secret retrieve OPENAI_API_KEY
hasp secret get
Retrieve a secret value only when you explicitly reveal or copy it. By default
this command shows secret metadata. Agents should use named refs with the MCP
broker path instead of raw get or reveal.
This verb stays for back-compat. Prefer the intent-named form:
hasp secret show metadata only
hasp secret reveal value to stdout
hasp secret copy value to the clipboard
When agent-safe mode is active, HASP blocks --reveal and --copy unless the
operator first grants one-time plaintext access with hasp session
grant-plaintext.
Examples
hasp secret get OPENAI_API_KEY
hasp secret retrieve OPENAI_API_KEY
hasp secret show
Print metadata for a secret: name, kind, created/updated timestamps, and any
exposures. The plaintext value is never printed by this command; use
hasp secret reveal or hasp secret copy when you need the value.
Examples
hasp secret show OPENAI_API_KEY
hasp secret reveal
Print the secret value to stdout. Opt-in by name, not by flag; the verb is the
intent. Subject to the same plaintext policy as the legacy get --reveal: in
agent-safe mode the operator must first grant one-time plaintext access with
hasp session grant-plaintext.
Examples
hasp secret reveal OPENAI_API_KEY
hasp secret copy
Copy the secret value to the clipboard without printing it. Subject to the same
plaintext policy as the legacy get --copy: in agent-safe mode the operator must
first grant one-time plaintext access with hasp session grant-plaintext.
Examples
hasp secret copy OPENAI_API_KEY
hasp secret list
List vault items and metadata, including the safe named_reference form such as
@OPENAI_API_KEY.
Examples
hasp secret list
hasp secret list --json
hasp secret diff
Compare a candidate .env file against the vault and report each KV name in one
of four buckets: same (value matches), changed (value differs), missing (in
vault but absent from .env), extra (in .env but absent from vault). Values are
read internally to classify but never written to stdout; only names appear in
output, so the command is safe to pipe into review tooling.
Examples
hasp secret diff .env
hasp secret diff config/.env.production --json
hasp secret expose
Expose one vault item to one repo boundary and create the repo-scoped reference
that brokered commands use.
Use expose when a repo needs a secret by reference, not by raw value.
Project binding alone does not expose existing vault items. This command updates
only project-binding metadata so @NAME resolves in that repo; it does not print
plaintext or write the secret into repo files.
Flags
--project-root <path> repo root to bind the secret to
--json emit machine-readable result on stdout
Examples
hasp secret expose OPENAI_API_KEY --project-root .
hasp secret expose OPENAI_API_KEY --project-root . --json
hasp secret hide
Remove one repo exposure for a secret. The vault item stays in the vault.
Flags
--project-root <path> repo root to remove the exposure from
--json emit machine-readable result on stdout
Examples
hasp secret hide OPENAI_API_KEY --project-root .
hasp secret hide OPENAI_API_KEY --project-root . --json
hasp app
Connect a normal application to selected vault secrets.
An app is machine-scoped by default. Add --project-root only when the app
should run inside a specific repo boundary.
Subcommands
connect save the app profile and optional launcher
run run the saved app command through HASP
install create or refresh the launcher
shell open a shell with the app bindings loaded
disconnect remove the app profile and managed launcher
list list saved apps
Learn more
hasp help app connect
hasp help app run
hasp app connect
Save an app profile that maps vault secrets to env vars, temporary files, or a
temporary dotenv bundle.
When the repo manifest declares a target, --target can seed the app command and
env/file mappings into the local app profile. The saved profile remains local
state after the manifest changes.
Launcher creation is never silent. In interactive use, HASP asks. In scripts,
set --install=always or --install=never. If you install a launcher and its
directory is not on PATH, HASP can also patch your shell config, but only after
you say yes or pass --add-to-path=always.
Tri-state flags (--install, --add-to-path, --install-hooks,
--auto-protect-repos, --enable-convenience-unlock, --overwrite-existing-config)
take always|never|ask. ask is the default and means "prompt when interactive".
The legacy true/false aliases are still accepted but will be removed.
Use NAME=@REF to reference vault items by name. Bare NAME=REF still resolves
during the deprecation window but emits a stderr warning.
Flags
--file <NAME=@REF> inject a secret as a temporary file (repeatable)
--target <name> seed command and delivery from a manifest target
--json emit machine-readable result on stdout
Examples
hasp app connect myapp --cmd 'python app.py' --env OPENAI_API_KEY=@OPENAI_API_KEY
hasp app connect myapp --cmd 'python app.py' --env OPENAI_API_KEY=@OPENAI_API_KEY --install=always --add-to-path=always
hasp app connect server-dev --project-root . --cmd 'make -C apps/server test-integration' --dotenv DATABASE_URL=@DATABASE_URL --dotenv-env ENV_FILE
hasp app connect server-dev --project-root . --target server.dev
hasp app run
Run the saved app command through HASP. Extra args after the app name are
forwarded to the saved command.
Examples
hasp app run myapp
hasp app run myapp --port 3000
hasp app install
Create or refresh the managed launcher for a saved app.
Use this when you skipped launcher creation during connect or when the launcher
path changed.
Flags
--json emit machine-readable result on stdout
Examples
hasp app install myapp
hasp app install myapp --add-to-path=always
hasp app shell
Open a login shell with the app bindings loaded. Extra args are forwarded to
the shell command.
Examples
hasp app shell myapp
hasp app disconnect
Remove the saved app profile. If HASP manages the launcher path, it removes the
launcher too.
Flags
--json emit machine-readable result on stdout
Examples
hasp app disconnect myapp
hasp app disconnect myapp --json
hasp app list
List saved apps.
Flags
--json emit machine-readable list on stdout
Examples
hasp app list
hasp app list --json
hasp agent
Connect a coding agent to HASP once, then let it pull secrets through the MCP
surface or the local config HASP writes.
Agents are usually repo-scoped. Pass --project-root when you want HASP to
bind the integration to one repo boundary.
Subcommands
connect write the agent config and save the agent record
mcp run the agent-specific HASP MCP wrapper
launch run a command under an agent-safe HASP session
shell open a shell under an agent-safe HASP session
disconnect remove the agent config block and the saved agent
list list saved agents
list-supported list shipped/generic profile support proof
Learn more
hasp help agent connect
hasp help agent mcp
hasp help agent launch
hasp help agent shell
hasp agent connect
Write the local agent config needed for HASP integration and save the agent
as a managed entry. Generated HASP MCP configs now point at a managed local
wrapper instead of a raw `hasp mcp` command so HASP can bind the
agent process tree to a protected session automatically.
Supported agent IDs:
claude-code, codex-cli, cursor write the agent's MCP config in place.
aider, hermes, openclaw install the wrapper at
$HASP_HOME/bin/hasp-agent-<id> and save the
managed entry; wire the wrapper into the
agent per docs/agent-profiles/<id>.md.
Flags
--project-root <path> repo root to bind the agent to (optional)
--json emit machine-readable result on stdout
Examples
hasp agent connect claude-code --project-root .
hasp agent connect codex-cli --project-root .
hasp agent connect cursor --project-root .
hasp agent connect aider --project-root .
hasp agent connect hermes --project-root .
hasp agent connect openclaw --project-root .
hasp agent mcp
Run the agent-specific HASP MCP wrapper. This opens an agent-safe session for
the saved agent, registers the parent agent process with the daemon, and then
serves MCP on stdin/stdout.
Use this as the generated config path instead of raw `hasp mcp` for
first-class agent profiles.
The default MCP catalog is safe-by-default: it can inspect project-scoped
metadata and deliver brokered refs, but it does not auto-expose secrets or
mutate vault/project state.
Examples
hasp agent mcp claude-code
hasp agent mcp codex-cli
hasp agent launch
Run a command under an agent-safe HASP session so subprocesses inherit
HASP_AGENT_SAFE_MODE and HASP_SESSION_TOKEN.
Use this when you want the whole agent process tree, not just the HASP MCP
server, to stay inside the protected policy context.
Examples
hasp agent launch claude-code -- claude
hasp agent launch codex-cli -- codex --model gpt-5.4
hasp agent shell
Open a shell under an agent-safe HASP session so anything launched from that
shell inherits HASP_AGENT_SAFE_MODE and HASP_SESSION_TOKEN.
Examples
hasp agent shell claude-code
hasp agent shell codex-cli -c 'env | grep HASP_'
hasp agent disconnect
Remove the HASP config block for one saved agent and delete the saved record.
Flags
--json emit machine-readable result on stdout
Examples
hasp agent disconnect claude-code
hasp agent disconnect claude-code --json
hasp agent list
List saved agents.
Flags
--json emit machine-readable list on stdout
Examples
hasp agent list
hasp agent list --json
hasp agent list-supported
List shipped and generic-compatible support profiles with docs, release-gate,
eval, benchmark, and connection proof.
Examples
hasp agent list-supported
hasp agent list-supported --json
hasp project
Manage repo boundaries. Projects are where HASP applies guardrails, alias maps,
and leak detection.
Subcommands
adopt scan a directory tree and bind matching git repos
bind bind one repo and create its initial alias map
doctor audit manifest-backed project-target setup without exposing values
examples check or write placeholder example files from the manifest
init create a value-free .hasp.manifest.json
requirements list manifest requirements, optionally filtered by target
status inspect one bound repo
target add value-free manifest targets
targets list manifest targets without command argv
unbind remove one repo binding
Common flags (all subcommands)
--json emit machine-readable result on stdout
--project-root <path> repo root (default: current directory)
project adopt flags
--under <path> directory tree to scan for git repos
--preview show what would be adopted without committing
project bind flags
--default-policy <p> default policy: auto|session|access
--hooks install git hooks in the repo (default: true)
--allow-non-git bind even if the path is not a git working tree
--alias <alias=item> add a repo alias mapping (repeatable)
project init flags
--name <name> project name stored in the value-free manifest
--description <text> human description stored in the manifest
project examples flags
--target <name> limit check/write to one manifest target
--check report stale or missing generated examples
--write write missing/stale generated examples
project target add flags
--root <path> target working directory inside the project
--env <NAME=@REF> deliver a named ref as an environment variable
(repeatable)
--file <NAME=@REF> deliver a named file ref as a broker-owned temp
file environment variable (repeatable)
--env-example <path> generate an env example from env deliveries
--description <text> human description stored in the value-free manifest
project target review flags
--json emit machine-readable result on stdout
Examples
hasp project init --project-root .
hasp project target add release.build --root apps/gum --env GUM_OAUTH_CLIENT_SECRET=@GUM_OAUTH_CLIENT_SECRET -- goreleaser release
hasp project target review release.build --project-root .
hasp project bind --project-root .
hasp project requirements --project-root .
hasp project targets --project-root . --json
hasp project examples --project-root . --target server.dev --check
hasp project doctor --project-root . --json
hasp project status --project-root .
hasp project adopt --under ~/Work
hasp project adopt --under ~/Work --preview
hasp project unbind --project-root .
hasp template
Alias for value-free HASP project manifest targets. A template is a committed
.hasp.manifest.json target: refs and delivery names only, never secret values.
Subcommands
init create .hasp.manifest.json
add add one value-free target
review record one target signature for local drift checks
list list manifest targets without command argv
doctor audit target setup without exposing values
Examples
hasp template init --project-root .
hasp template add release.build --root apps/gum --env GUM_OAUTH_CLIENT_SECRET=@GUM_OAUTH_CLIENT_SECRET -- goreleaser release
hasp template review release.build --project-root .
hasp template list --project-root .
hasp run
Run one repo-scoped command through the broker with time-bound secret grants.
Use run when you want the repo boundary, approval model, and audit trail. Use
app run when you want a saved app.
Flags
--project-root <path> repo root to use for binding and grant checks
--target <name> resolve env/file mappings from one manifest target
--session-token <token> use an existing session token instead of
opening a new one
--grant-project <scope> project grant scope: window or session
--grant-secret <scope> secret grant scope: window or session
--grant-window <duration> maximum age for a grant (e.g. 15m, 1h)
--env <NAME=@REF> inject a secret as an env var (repeatable)
--file <NAME=@REF> inject a secret as a temp file (repeatable)
--explain print the resolved decision tree before
executing (output goes to stderr)
--dry-run print the decision tree and exit without
executing (use with --explain)
--explain-format <fmt> text (default) or json
Examples
hasp run --project-root . --env OPENAI_API_KEY=@OPENAI_API_KEY -- npm test
hasp run --project-root . --target server.dev --grant-project window --grant-secret session
hasp run --project-root . --env OPENAI_API_KEY=@OPENAI_API_KEY --explain --dry-run -- pytest tests/
hasp run --project-root . --grant-window 15m --grant-secret window -- python script.py
hasp inject
Resolve repo-scoped refs into env vars or temporary files for one command.
Use inject for low-level brokered execution. Saved apps (hasp app run) are
the simpler path for repeatable non-repo apps.
Authorization preview
--explain print the resolved decision tree (project lease, secret
grant, grant window, redactor) before executing.
--explain --dry-run print the decision tree and exit without executing.
Examples
hasp inject --project-root . --file GOOGLE_APPLICATION_CREDENTIALS=@GOOGLE_APPLICATION_CREDENTIALS -- gcloud auth list
hasp inject --project-root . --target release.sign -- ./deploy.sh
hasp write-env
Write a convenience env file from repo-scoped refs after explicit approval.
Use this when a tool truly needs a file on disk. Brokered run and inject are
safer because they avoid leaving values in the repo.
Flags
--project-root <path> repo root to use for grant checks
(default: current directory)
--target <name> resolve env mappings from one manifest target
--output <path> destination file for the env block
--env <NAME=@REF> inject a secret as an env var (repeatable)
--json emit machine-readable result on stdout
--session-token <token> use an existing broker session token
--grant-project <scope> project grant scope: once|session|window|<dur>
--grant-secret <scope> secret grant scope: once|session|window|<dur>
--grant-convenience <scope> convenience grant scope: once|window|<dur>
--grant-window <duration> maximum age for any grant (e.g. 15m)
--force overwrite an existing file (exclusive with
--append)
--append merge values into a delimited hasp block
inside an existing file idempotently
Examples
hasp write-env --project-root . --output .env.local --env OPENAI_API_KEY=@OPENAI_API_KEY
hasp write-env --project-root . --target build.config --grant-convenience window
hasp write-env --project-root . --output .env.local --env OPENAI_API_KEY=@OPENAI_API_KEY --force
hasp write-env --project-root . --output .env.local --env OPENAI_API_KEY=@OPENAI_API_KEY --append
hasp check-repo
Scan a repo for managed values that leaked into files.
Flags
--project-root <path> repo root to scan (default: current directory)
--json emit machine-readable result on stdout
--staged scan the staged index content (what the commit will
contain) instead of the working tree; used by the
pre-commit hook so a staged-then-overwritten secret
cannot slip past
--fail-on-skipped exit non-zero if any file was skipped (e.g. over the
size cap) and therefore not scanned
--allow-managed-secrets suppress exit-1 even when managed values are found
(also bypasses the locked-vault block); useful in CI
scenarios that treat the scan as advisory only
Examples
hasp check-repo --project-root .
hasp check-repo --project-root . --json
hasp check-repo --project-root . --staged # pre-commit: scan staged content
hasp proof
Run the brokered first-proof check. Verifies that the named secret is bound
to the project and reachable through the broker's normal run flow, then
reports PASS / FAIL on stdout (and propagates exit code).
This collapses the long quickstart one-liner
hasp run --project-root <p> --env HASP_SETUP_PROOF=@SECRET --grant-project window \
--grant-secret session --grant-window 15m -- sh -c 'test -n "$HASP_SETUP_PROOF"'
into a single command.
Required
--secret <name|alias> the secret reference to inject under HASP_SETUP_PROOF
Optional
--project-root <path> defaults to the current directory
Examples
hasp proof --secret api_token
hasp proof --project-root /path/to/repo --secret secret_01
hasp daemon
Manage the local runtime daemon.
Subcommands
run run the daemon in the foreground (LaunchAgent entry point)
serve run the daemon in the foreground
start start it in the background
stop stop it
restart lock the vault, stop the daemon, then start it again
status inspect it
http-key inspect or reinitialise the daemon HTTP HMAC key
Examples
hasp daemon run --foreground --gui-listener
hasp daemon status
hasp daemon restart --reason app-update
hasp daemon http-key fingerprint
hasp daemon http-key reinitialize
hasp session
Work with broker sessions directly.
Subcommands
open open a session for one repo boundary
list list active broker sessions (--mine restricts to the calling user)
grant-plaintext grant one-time plaintext reveal/copy for a protected session
grant-mutation grant one-time secret delete/expose/hide for MCP mutation
resolve inspect an existing token
revoke revoke an existing token
Common flags
--json emit machine-readable result on stdout
session open flags
--project-root <p> repo root to open the session for
--host-label <lbl> label to identify this client (default: generic-client)
session list flags
--mine restrict to sessions owned by the calling user
session resolve / revoke flags
--token <token> session token to inspect or revoke
--all revoke all active sessions (revoke only; exclusive with
--token)
Examples
hasp session open --host-label local-cli --project-root .
hasp session grant-mutation --token $HASP_SESSION_TOKEN --item API_TOKEN --action expose
hasp session list --mine
hasp session resolve --token $HASP_SESSION_TOKEN
hasp session revoke --token $HASP_SESSION_TOKEN
hasp session revoke --all
hasp session grant-plaintext
Grant one-time plaintext reveal/copy for an agent-safe session.
Use this as an explicit operator step before retrying `hasp secret get --reveal`
or `--copy` inside a protected agent workflow. Approval is interactive
and local, and plaintext grants stay one-time, item-scoped, action-scoped, and
short-lived.
Flags
--token <token> agent-safe session token to grant against
--item <name> vault item name to grant plaintext access for
--action <reveal|copy> the plaintext action to permit
--scope <scope> grant scope (default: once)
--grant-window <dur> maximum lifetime for the grant (default: 60s)
--json emit machine-readable result on stdout
Examples
hasp session grant-plaintext --token $HASP_SESSION_TOKEN --item OPENAI_API_KEY --action reveal --grant-window 60s
hasp session grant-plaintext --token $HASP_SESSION_TOKEN --item OPENAI_API_KEY --action copy --grant-window 60s
hasp session grant-mutation
Grant one-time secret delete/expose/hide authority for an agent-safe session.
Use this as an explicit local operator step before enabling MCP destructive
secret tools. The MCP request still names the item and action, but only this
persisted, one-time grant authorizes the mutation.
Normal MCP setups should not need this command. Trusted local harnesses must
both set HASP_MCP_ENABLE_UNSAFE_SECRET_WRITE_TOOLS=1 and grant the matching
mutation before hasp_secret_expose, hasp_secret_hide, or hasp_secret_delete can
succeed.
Flags
--token <token> agent-safe session token to grant against
--item <name> vault item name to permit mutation for
--action <delete|expose|hide> mutation action to permit
--scope <scope> grant scope (default: once)
--grant-window <dur> maximum lifetime for the grant (default: 60s)
--json emit machine-readable result on stdout
Examples
hasp session grant-mutation --token $HASP_SESSION_TOKEN --item OPENAI_API_KEY --action expose --grant-window 60s
hasp session grant-mutation --token $HASP_SESSION_TOKEN --item OPENAI_API_KEY --action hide --grant-window 60s
hasp lease
List or revoke broker leases exposed through the daemon API.
Subcommands
list list leases with optional consumer, status, expiry, and cursor filters
revoke revoke one lease id or every active lease for a consumer
Common flags
--json emit machine-readable result on stdout
Examples
hasp lease list --json
hasp lease list --consumer ci-runner --status active
hasp lease revoke <lease-id> --reason operator-request
hasp lease revoke --all-for-consumer ci-runner
hasp lease list
List leases using the same response schema as GET /v1/leases.
Flags
--json emit machine-readable result on stdout
--consumer <id> filter to one consumer id
--status <status> filter to active, revoked, or expired leases
--expiring-in <dur> filter active leases expiring within a duration
--cursor <cursor> pagination cursor from next_cursor
--limit <n> maximum rows to return (default: 100)
Examples
hasp lease list --json
hasp lease list --consumer ci-runner --status active
hasp lease list --expiring-in 10m --limit 25
hasp lease revoke
Revoke a lease by id, or revoke every active lease for one consumer.
Flags
--json emit machine-readable result on stdout
--reason <text> reason recorded with the revoke audit event
--all-for-consumer <id> revoke all active leases for one consumer id
Examples
hasp lease revoke <lease-id> --reason operator-request
hasp lease revoke --all-for-consumer ci-runner --reason cleanup
hasp approval
List broker approval requests.
Subcommands
list list approval requests by status or consumer
Common flags
--json emit machine-readable result on stdout
Examples
hasp approval list --json
hasp approval list --status pending --consumer ci-runner
hasp approval list
List approval requests using the same response schema as GET /v1/approvals.
Flags
--json emit machine-readable result on stdout
--status <state> filter to pending, granted, denied, or expired
--consumer <id> filter to one requester consumer id
Examples
hasp approval list --json
hasp approval list --status pending
hasp approval list --consumer ci-runner
hasp access
Inspect read-side access surfaces exposed through the daemon API.
Subcommands
matrix show the sparse consumer by secret grant matrix
Common flags
--json emit machine-readable result on stdout
Examples
hasp access matrix --json
hasp access matrix --consumer ci-runner --json
hasp access matrix
Show the same sparse matrix schema as GET /v1/access/matrix.
Flags
--json emit machine-readable result on stdout
--consumer <id> filter to one consumer id
--secret <id> filter to one secret id or path
--scope <scope> filter to one grant scope
--source <source> filter to policy or manual grants
--has-active-lease <bool> filter by active lease presence
--cursor <cursor> pagination cursor from next_cursor
--limit <n> maximum grant rows to return (default: 100)
Examples
hasp access matrix --json
hasp access matrix --consumer ci-runner --json
hasp access matrix --source manual --has-active-lease true
hasp policy
Show, validate, or replace daemon policy rules.
Subcommands
show print the current policy document
set replace the policy from a JSON file
validate validate a policy JSON file without persisting it
Examples
hasp policy show --json
hasp policy validate --file policy.json
hasp policy set --file policy.json
hasp policy set --file policy.json --force
hasp policy show
Print the current policy document using the same schema as GET /v1/policy.
Options
--json emit machine-readable JSON
Examples
hasp policy show
hasp policy show --json
hasp policy set
Replace the current policy from a JSON file. The file's version is used as the
optimistic concurrency precondition unless --force is passed.
Options
--file <path> policy JSON file to apply
--force skip version precondition; validation still runs
--json emit machine-readable JSON
Examples
hasp policy set --file policy.json
hasp policy set --file policy.json --force --json
hasp policy validate
Validate a policy JSON file through the daemon without persisting it.
Options
--file <path> policy JSON file to validate
--json emit machine-readable JSON
Examples
hasp policy validate --file policy.json
hasp policy validate --file policy.json --json
hasp config
Show, read, or update whitelisted daemon settings.
Subcommands
show print the full safe config map
get print one config key
set update one config key
Examples
hasp config show --json
hasp config get vault.idle_relock_s
hasp config set reveal.scrub_seconds 45
hasp config show
Print the full safe config map. Secret material such as HMAC keys, master
password material, and license blobs is never part of this surface.
Options
--json emit machine-readable JSON
Examples
hasp config show
hasp config show --json
hasp config get
Print one whitelisted config key.
Options
--json emit machine-readable JSON
Examples
hasp config get vault.auto_relock_enabled
hasp config get integrations.disabled_targets --json
hasp config set
Update one whitelisted config key. Values are typed by key: booleans use
true/false, numbers use decimal integers, arrays use JSON string arrays.
Options
--json emit machine-readable JSON
Examples
hasp config set clipboard.scrub_seconds 90
hasp config set ui.reduce_motion_override on
hasp config set integrations.disabled_targets '["shell-hook"]'
hasp telemetry
Inspect or change optional CLI telemetry. Telemetry is disabled by default and
requires explicit opt-in through setup or `hasp telemetry enable`.
Telemetry sends daily aggregate command and reliability counters only. It never
sends secrets, secret names, aliases, refs, paths, repo names, command args,
stdout/stderr, raw errors, stack traces, or audit logs.
Set HASP_TELEMETRY_DISABLED=1 to block telemetry regardless of saved consent.
Subcommands
status show consent, env override, endpoint, last ping, and schema
enable opt in after a policy summary and confirmation
disable withdraw consent and stop collection/sending
forget delete local telemetry identity/counters and request erasure
preview print the exact payload that would be sent, without sending it
Options
--json emit machine-readable JSON
--yes skip the interactive confirmation for enable
Examples
hasp telemetry status
hasp telemetry enable
hasp telemetry preview --json
hasp telemetry forget
hasp vault
Manage local vault/session material.
Subcommands
lock revoke active sessions and grants AND forget the saved keychain unlock
forget-device forget only the saved keychain unlock (keeps sessions intact)
rekdf re-derive the password wrap under the binary's current default KDF (e.g. argon2id)
rekey rotate the master password without rotating the underlying vault key
Common flags
--json emit machine-readable result on stdout (lock, forget-device, rekdf)
Examples
hasp vault lock
hasp vault forget-device
hasp vault rekdf
hasp vault rekdf --json
HASP_MASTER_PASSWORD=old HASP_NEW_MASTER_PASSWORD=new hasp vault rekey
hasp vault lock
Revoke active daemon sessions and local grant material, AND forget the saved
keychain (convenience) unlock: clearing the envelope's ConvenienceWrap and
deleting the keychain item. This does not rotate provider credentials.
Use this as the "walking-away-from-the-machine" big red button: next time the
vault opens, a same-uid attacker cannot replay a stored keychain key, and
every in-flight grant and session is gone.
Examples
hasp vault lock
hasp vault lock --json
hasp vault forget-device
Forget the saved keychain (convenience) unlock for this vault. Two effects,
both of which must happen for the operation to count:
1. Clear the envelope's ConvenienceWrap so OpenWithConvenienceUnlock can no
longer revive the vault without the master password.
2. Delete the keychain item so a same-uid attacker cannot read the wrapped
key off disk and replay it.
This is narrower than `hasp vault lock`: it leaves active daemon
sessions and grant material alone. Use it when you want to revoke the "stay
unlocked on this device" shortcut without interrupting an in-flight session,
or when rotating the keychain-held device key as part of an incident response.
The command is idempotent: running it twice is safe and exits 0 both times.
Examples
hasp vault forget-device
hasp vault forget-device --json
hasp vault rekey
Rotate the master password that protects the vault. The underlying vault key
(and therefore every sealed item) is preserved; only the password wrap is
re-derived under the new password. Use this when the master password may have
been observed or simply on a regular cadence.
Both passwords are read from the environment so they never touch shell history
or argv:
HASP_MASTER_PASSWORD current master password
HASP_NEW_MASTER_PASSWORD new master password to install
Side effects (atomic with the password rotation):
- Clears the saved convenience-unlock wrap (you must re-enable it after
rekey if you still want keychain-backed unlock on this device).
- Writes a single audit event of type `rekey`; password values are
never recorded.
The old password no longer unlocks the vault after the call returns.
Examples
HASP_MASTER_PASSWORD=$old HASP_NEW_MASTER_PASSWORD=$new hasp vault rekey
HASP_MASTER_PASSWORD=$old HASP_NEW_MASTER_PASSWORD=$new hasp vault rekey --json
hasp status
Show local daemon and vault status.
Examples
hasp status
hasp status --json
hasp ping
Check whether the local daemon can answer requests.
Flags
--json emit machine-readable result on stdout
Examples
hasp ping
hasp ping --json
hasp audit
Print the local audit log.
Subcommands
tail print the most recent events; -f streams new appends
verify verify the local audit chain HMAC and exit
export stream audit events as NDJSON with a trailer HMAC
recover archive a degraded audit log and start a fresh chain
Flags
--json emit one JSON event per line (NDJSON)
--format <fmt> output format: timeline, table, or json
--verify verify the audit chain HMAC and exit (alias for
the verify subcommand)
--secret <ref> filter by Details.reference
--project-root <path> filter by Details.project_root
--agent <name> filter by Details.agent
--action <name> filter by Details.action
--blocked only show blocked events
--since <time> only show events after this RFC3339 timestamp or
Go duration (e.g. 1h)
Examples
hasp audit
hasp audit --incident-bundle --json
hasp audit export --from 2026-05-10T00:00:00Z --to 2026-05-10T01:00:00Z
hasp audit recover --reason "duplicate append at sequence 889"
hasp audit tail -n 20 -f
hasp audit export
Stream audit events as NDJSON and append a trailer line containing the SHA-256
of streamed event bytes, HMAC, and count.
Flags
--from <time> include events at or after this RFC3339 timestamp
--to <time> include events at or before this RFC3339 timestamp
--format <fmt> output format (currently ndjson)
Examples
hasp audit export --format ndjson
hasp audit export --from 2026-05-10T00:00:00Z --to 2026-05-10T01:00:00Z
hasp audit recover
Archive a degraded audit log and start a fresh audit chain with a recovery
marker. This command does not rewrite tamper-evident history: it moves the
existing audit.jsonl into a recovery directory, writes a signed recovery report,
and records the archive digest in the first event of the new chain.
Flags
--output <dir> recovery directory (default: $HASP_HOME/audit-recovery/<timestamp>)
--reason <text> operator reason stored in the recovery report and marker
--force rotate even when the current audit chain verifies
--json emit machine-readable recovery metadata
Examples
hasp audit recover --reason "duplicate append at sequence 889"
hasp audit recover --output ~/Desktop/hasp-audit-recovery --json
hasp audit tail
Print the most recent audit events. With --follow, keep streaming new appends
until interrupted.
Flags
--n N, -n N show the last N events (default: 50)
--f, -f stream new events as they are appended (short for --follow)
--follow stream new events as they are appended
--all show all stored events (mutually exclusive with -n)
--since <dur> only show events newer than this duration ago (e.g. 1h)
--json emit one JSON event per line (NDJSON)
--secret REF filter by Details.reference
--project-root P filter by Details.project_root
--agent NAME filter by Details.agent
--action NAME filter by Details.action
--blocked only show blocked events
Examples
hasp audit tail
hasp audit tail -n 20 -f
hasp audit tail --all --since 1h
hasp audit tail -f --json --action secret.get.plaintext_blocked
hasp export-backup
Write an encrypted backup for the local vault.
Flags
--output <path> destination file for the encrypted backup
--recovery-passphrase <pp> passphrase protecting the backup (prefer stdin
or fd forms to avoid argv exposure)
--recovery-passphrase-stdin read passphrase from stdin (until EOF or newline)
--recovery-passphrase-fd N read passphrase from file descriptor N
--json emit machine-readable result on stdout
The passphrase may also be supplied via the HASP_BACKUP_PASSPHRASE environment
variable. Passing it directly on the command line is not allowed.
Examples
echo "$PP" | hasp export-backup --output backup.json --recovery-passphrase-stdin
hasp export-backup --output backup.json --recovery-passphrase-fd 3 3<<<"$PP"
hasp export-backup --output backup.json --recovery-passphrase-stdin --json
hasp restore-backup
Restore an encrypted backup into the current HASP home.
Flags
--input <path> source file for the encrypted backup
--recovery-passphrase-stdin read passphrase from stdin (until EOF or newline)
--recovery-passphrase-fd N read passphrase from file descriptor N
--recovery-passphrase <pp> passphrase on argv (UNSAFE; rejected at runtime;
use the stdin or fd form instead)
--master-password <pw> master password on argv (UNSAFE; rejected at
runtime; use HASP_MASTER_PASSWORD instead)
--json emit machine-readable result on stdout
The passphrase may also be supplied via HASP_BACKUP_PASSPHRASE. The master
password must be provided via HASP_MASTER_PASSWORD. Passing secrets directly
on the command line is not allowed.
Examples
echo "$PP" | hasp restore-backup --input backup.json --recovery-passphrase-stdin
hasp restore-backup --input backup.json --recovery-passphrase-fd 3 3<<<"$PP"
hasp mcp
Start the MCP server on stdin and stdout.
Use this from agent configs, not by hand, unless you are debugging the MCP
transport.
Examples
hasp mcp
hasp tui
Deprecated. `hasp tui` does not open a real terminal UI; it prints a
one-shot key/value snapshot of the current project binding (canonical root,
visible refs, vault item count) and exits. The name was aspirational and is
kept only so older scripts keep working.
Use `hasp project status` for the structured project view going forward.
The snapshot output remains stable for back-compat, but `hasp tui` will
print a deprecation warning to stderr on every invocation.
Flags
--json emit the snapshot as JSON instead of the aligned table
--project-root PATH project directory to inspect (default: current dir)
Examples
hasp project status # recommended replacement
hasp tui # legacy snapshot (prints deprecation warning)
hasp tui --json # legacy snapshot as JSON
hasp version
Print the build version.
Flags
--json emit machine-readable version envelope on stdout
Examples
hasp version
hasp version --json
hasp completion
Emit a shell completion script for bash, zsh, fish, or powershell on stdout.
The completable commands are derived from the live command inventory so the
script never lags the dispatcher.
Examples
hasp completion bash >> ~/.bashrc
hasp completion zsh > ~/.config/zsh/_hasp
hasp completion fish > ~/.config/fish/completions/hasp.fish
hasp completion powershell | Out-String | Invoke-Expression
hasp upgrade
Download a newer signed hasp release and atomically replace the running
binary. Verification chain (fail-closed at every step):
1. The release ships a KEYS file listing currently-trusted Ed25519
public keys, signed by at least one key embedded in this binary.
2. The tarball is signed by some key listed in the verified KEYS file.
3. The downloaded tarball replaces the running binary via rename(2)
on the same filesystem (atomic; the old inode keeps running until
this process exits).
Refusals (no on-disk side effects):
- --version is older than or equal to the installed version
(rollback protection)
- KEYS file is not signed by any embedded trust root
- tarball is not signed by any KEYS-listed key
- artifact URL is not on github.com
- this build has no embedded release keys (unsigned 'go build')
Flags
--version vX.Y.Z target release tag (required)
--yes skip the interactive confirm prompt
--json emit a JSON report on stdout
Examples
hasp upgrade --version v0.2.0
hasp upgrade --version v0.2.0 --yes
hasp upgrade --version v0.2.0 --json --yes
Find releases at https://github.com/gethasp/hasp/releases.
hasp docs
Render reference documentation from the live help topic inventory. Useful for
shipping a single offline reference page alongside the binary and for
downstream packagers who want the same source of truth as the CLI.
Subcommands
markdown render every help topic as one markdown page
Examples
hasp docs markdown --out docs/cli.md
hasp help internals
Lower-level vocabulary for operators, integrators, and adversarial reviewers.
Most users never need these terms; the four root concepts (vault, repo, agent,
grant) cover the daily surface.
Vault and secrets
vault encrypted local store under HASP_HOME.
secret one named item in the vault.
alias a per-repo nickname mapped to a vault secret name. Lets a
command see "API_TOKEN" while the vault stores "stripe_live".
reference a structured pointer to a vault item ("@my_secret") that
resolves to a value at delivery time.
named reference an alias used as a reference inside an agent or app profile.
exposure the policy on a secret that controls whether it may be
injected into env, written to a file, or held vault-only.
Repo (project) surface
project a git-backed root path bound to the broker.
binding the saved record that ties a repo path to a set of secrets,
aliases, and grant defaults.
consumer an app or agent profile attached to a repo. The same secret
can flow to multiple consumers under different aliases.
Broker and grants
broker the local runtime that mediates every secret delivery.
grant one short-lived permission to deliver one secret to one run.
Carries a scope (project/secret/window) and a lease.
lease the time-bounded handle the broker holds for an active grant.
Ends on window expiry, manual revoke, or process exit.
scope the (project root, secret, window) tuple that limits a grant.
session token the in-memory handle the daemon issues to a CLI process for
one open session. Never written to disk; binds to a peer PID.
Redactor encoding coverage
The redactor scans output for every encoded form of each managed secret.
Encoding forms currently masked (minRedactLen=6 bytes minimum value length):
raw literal bytes
base64-std RFC 4648 standard alphabet with padding
base64-url URL-safe alphabet with padding
base32-std RFC 4648 standard alphabet with padding
hex-lower lowercase hex (0-9, a-f)
hex-upper uppercase hex (0-9, A-F)
url-encoded percent-encoded query-string form
json-escaped JSON string body escapes (e.g. \n, \t, \\)
html-entity per-byte hex entity (A etc.)
double-percent percent-encode then re-encode % signs (%2541 etc.)
unicode-escape per-codepoint \uXXXX form
Markers are NOT length-preserving. A 4096-byte secret becomes "[REDACTED]"
(10 bytes); encoded forms become "[REDACTED_B64]", "[REDACTED_HEX]", etc.
Byte offsets and line lengths after a managed value will shift, so column-
aware log shippers and byte-position diff tools must not assume the pre-
redaction layout. Line counts are preserved (no marker contains '\n').
Audit and verification
audit chain append-only HMAC-chained log of every grant decision.
See: hasp audit / hasp audit tail.
fail-closed the broker default: if any check fails (peer UID/PID,
expiry, revoked grant, missing capability), no value is
delivered.
Examples
hasp help grant
hasp audit tail --json
hasp doctor
hasp help exit-codes
Every hasp command exits with a stable bucket so scripts can branch on
machine-readable failure without parsing strings. The same buckets back the
"code" field in --json error envelopes.
0 ok command succeeded
1 generic / internal uncategorised failure (E_INTERNAL or no envelope)
2 user input missing flag, malformed grammar, not in a repo
(E_USER_INPUT, E_NOT_IN_REPO)
3 permission vault locked, wrong password, grant denied
(E_PERMISSION, E_VAULT_LOCKED, E_PASSWORD_WRONG,
E_GRANT_DENIED)
4 daemon / I/O daemon unreachable or broker timeout
(E_DAEMON_UNREACHABLE)
5 leak detected repo scan found managed values in the working tree
(E_REPO_LEAK)
6 not found named secret/binding/grant is not in the vault
(E_NOT_FOUND)
Examples
hasp secret show DOES_NOT_EXIST # exits 6 (E_NOT_FOUND)
hasp secret show ANY --json # exits 3 if vault is locked
hasp check-repo --project-root . # exits 5 if a managed value is on disk
Scripts should branch on the bucket, not the message text:
hasp secret show "$NAME" >/dev/null
case $? in
0) echo "ok" ;;
6) echo "not found" ;;
3) echo "vault locked or grant denied" ;;
*) echo "other error: $?" ;;
esac