Skip to content

Latest commit

 

History

History
2005 lines (1519 loc) · 63 KB

File metadata and controls

2005 lines (1519 loc) · 63 KB

HASP CLI reference

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.

Root help

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

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

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

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

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

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

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

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

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

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

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

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

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

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 retrieve

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

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

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

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

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

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

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

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

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

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

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

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

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

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

hasp app list

List saved apps.

Flags
  --json   emit machine-readable list on stdout

Examples
  hasp app list
  hasp app list --json

hasp agent

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

hasp status

Show local daemon and vault status.

Examples
  hasp status
  hasp status --json

hasp ping

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

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

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

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

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

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

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

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

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

hasp version

Print the build version.

Flags
  --json   emit machine-readable version envelope on stdout

Examples
  hasp version
  hasp version --json

hasp completion

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

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

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 internals

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 (&#x41; 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 exit-codes

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