Reference
CLI reference
Exact help output generated by the installed hasp binary.
Build: 0.1.36 (unknown)
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 conceptsvault encrypted local store of named secrets under HASP_HOMErepo a project root you bind so commands run inside it can pull secretstarget a repo-declared delivery subset; never an authority by itselfagent a connected app or coding agent that gets brokered accessgrant short-lived, scoped permission to deliver a secret to one runStart herehasp setuphasp secret addhasp agent connect <profile> --project-root .hasp proof --secret <name-or-alias>For lower-level vocabulary (operator/integrator surface) see: hasp help internalsDaily commandssetup guided machine, repo, and agent setupdoctor diagnose daemon, vault, binding, hooks, and audit statesecret add, update, show/reveal/copy, expose, and hide vault itemsapp connect an app profile and run it with managed secretsagent connect an agent once and let it pull through HASPrun run a repo-scoped command through the brokerinject run a command with env or file refs resolved by HASPproof run the brokered first-proof check (replaces the long quickstart one-liner)Help topicshasp help setuphasp help secrethasp help secret addhasp help apphasp help app connecthasp help agenthasp help agent connecthasp help runhasp help injecthasp help doctorAdvanced and automationhasp help internalshasp help check-repohasp help write-envhasp help completionhasp help docsOutput--json machine-readable output on stdout for status, list, and mutation commands.errors are emitted as a single JSON envelope on stderr with stableerror 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 initCreate the local encrypted vault under HASP_HOME.Use this once per machine or once per HASP_HOME.Flags--json emit machine-readable result on stdoutExampleshasp inithasp init --json
hasp setup
hasp setupGuide a user through machine setup. This command can choose the HASP home,optionally bind one repo, optionally skip agent setup, and in interactive usecontinue into adding secrets or connecting an app.Use setup when you want one guided flow. Use the lower-level commands when youalready know the exact state you want.Master password policyNewly created vaults require a master password of at least 12 characterswith more than one distinct character. Pass --skip-password-policy if yourorganisation enforces its own policy upstream (corporate password manager,FIDO-derived secret, etc.).Flags--non-interactive run without prompts; all required values mustbe 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 configExampleshasp setuphasp setup --non-interactive --hasp-home ~/.hasp --project-root . --agent claude-code
hasp bootstrap
hasp bootstrapConfigure a repo and an agent profile in one operator-focused flow. Bootstrapexists for repo-first workflows. The newer app- and agent-first path is usually:hasp secret addhasp agent connect claude-code --project-root .Subcommandsgeneric write a generic agent profile for the current repodoctor diagnose a previously bootstrapped repo/profile pairMaster password policyWhen bootstrap creates a new vault from HASP_MASTER_PASSWORD it enforces aminimum-length and basic-entropy check (at least 12 characters and morethan one distinct character). Pass --skip-password-policy when an upstreampolicy 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)Exampleshasp bootstrap --profile claude-code --project-root .hasp bootstrap generic --project-root .hasp bootstrap doctor --profile claude-code --project-root .
hasp doctor
hasp doctorDiagnose local HASP health without exposing secrets or reconnaissance-heavydetails 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; thelive daemon's socket is a unix domain socket, not a regularfile, 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)--json emit machine-readable result on stdout--fix attempt to repair common breakage (see above)Exampleshasp doctorhasp doctor --jsonhasp doctor --fix
hasp import
hasp importImport secrets from a .env file or a JSON credential file. You can also rescuepasted values or shell-style `export FOO=bar` snippets by piping them onstdin 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 wouldchange before it commits.Use import when you already have secrets on disk, in the clipboard, or in anambient shell session and want to move them into the vault without leaving themin `.env` or shell profiles. Use secret add when you want to enter valuesdirectly.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, jsonExampleshasp import .envhasp import service-account.jsonhasp import --project-root . --bind .envprintf '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 fornon-interactive scripts). 'hasp set' still works for one release.Prefer --value-stdin over --value: --value places the plaintext on argv whereps, shell history, and accounting logs can see it. --value still works butemits 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 stdoutExamplesprintf 'sk-123' | hasp secret add --vault-only --from-stdin OPENAI_API_KEYhasp set --name CERT_FILE --kind file --from-file cert.pemhasp 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 alreadyhave 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 captureExampleshasp capture --name api_token --value abc123hasp capture --name api_token --value abc123 --project-root . --bind
hasp secret
hasp secretWork with the one local vault. These commands do not create new vaults per repoor per app.Subcommandsadd add one or more secretsupdate replace existing secret valuesrotate replace a value for incident response and revoke grantsdelete remove secrets from the vaultshow 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 workretrieve alias for secret getlist list secret names and metadatasearch filter the inventory by a case-insensitive substring on the namediff compare a candidate .env file against the vault by name onlyexpose bind a secret to a repo boundary and create a referencehide remove one repo exposure for a secretCommon flags--json emit machine-readable output on stdout (all subcommands thatproduce structured output honour this flag)Learn morehasp help secret addhasp help secret expose
hasp secret add
hasp secret addAdd one or more secrets to the vault. In a repo, HASP can also expose the newsecret to that repo boundary, but only with explicit operator consent: ininteractive 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 hiddenprompt or from stdin via --from-stdin. NAME=VALUE on argv is rejected becauseps, 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 repoExampleshasp secret addhasp secret add OPENAI_API_KEYhasp secret add --vault-onlyhasp secret add --expose=always TOKENprintf 'sk-123' | hasp secret add --from-stdin --expose=never OPENAI_API_KEYhasp secret add --kind file --from-file cert.pem CERT_FILE
hasp secret update
hasp secret updateReplace the value for one or more existing secrets.Flags--json emit machine-readable result on stdoutExampleshasp secret update OPENAI_API_KEYhasp secret update
hasp secret rotate
hasp secret rotateReplace a local HASP secret value for incident response and invalidate activegrants for that local item. Provider-side credential rotation remains theoperator's responsibility.The new value comes from a hidden prompt (or piped stdin); NAME=VALUE on argvis rejected because ps, shell history, and accounting logs can see it.Flags--json emit machine-readable result on stdoutExampleshasp secret rotate OPENAI_API_KEYhasp secret rotate --json OPENAI_API_KEYprintf 'new-local-value' | hasp secret rotate OPENAI_API_KEY
hasp secret delete
hasp secret deleteDelete one or more secrets from the vault. HASP asks for confirmation unlessyou pass --yes.Flags--json emit machine-readable result on stdout--yes skip the confirmation promptExampleshasp secret delete OPENAI_API_KEYhasp secret delete --yes OPENAI_API_KEYhasp secret delete --json OPENAI_API_KEY
hasp secret get
hasp secret getRetrieve a secret value only when you explicitly reveal or copy it. By defaultthis command shows secret metadata. Agents should use named refs with the MCPbroker path instead of raw get or reveal.This verb stays for back-compat. Prefer the intent-named form:hasp secret show metadata onlyhasp secret reveal value to stdouthasp secret copy value to the clipboardWhen agent-safe mode is active, HASP blocks --reveal and --copy unless theoperator first grants one-time plaintext access with hasp sessiongrant-plaintext.Exampleshasp secret get OPENAI_API_KEYhasp secret retrieve OPENAI_API_KEY
hasp secret retrieve
hasp secret getRetrieve a secret value only when you explicitly reveal or copy it. By defaultthis command shows secret metadata. Agents should use named refs with the MCPbroker path instead of raw get or reveal.This verb stays for back-compat. Prefer the intent-named form:hasp secret show metadata onlyhasp secret reveal value to stdouthasp secret copy value to the clipboardWhen agent-safe mode is active, HASP blocks --reveal and --copy unless theoperator first grants one-time plaintext access with hasp sessiongrant-plaintext.Exampleshasp secret get OPENAI_API_KEYhasp secret retrieve OPENAI_API_KEY
hasp secret show
hasp secret showPrint metadata for a secret: name, kind, created/updated timestamps, and anyexposures. The plaintext value is never printed by this command; usehasp secret reveal or hasp secret copy when you need the value.Exampleshasp secret show OPENAI_API_KEY
hasp secret reveal
hasp secret revealPrint the secret value to stdout. Opt-in by name, not by flag — the verb is theintent. Subject to the same plaintext policy as the legacy get --reveal: inagent-safe mode the operator must first grant one-time plaintext access withhasp session grant-plaintext.Exampleshasp secret reveal OPENAI_API_KEY
hasp secret copy
hasp secret copyCopy the secret value to the clipboard without printing it. Subject to the sameplaintext policy as the legacy get --copy: in agent-safe mode the operator mustfirst grant one-time plaintext access with hasp session grant-plaintext.Exampleshasp secret copy OPENAI_API_KEY
hasp secret list
hasp secret listList vault items and metadata, including the safe named_reference form such as@OPENAI_API_KEY.Exampleshasp secret listhasp secret list --json
hasp secret diff
hasp secret diffCompare a candidate .env file against the vault and report each KV name in oneof four buckets: same (value matches), changed (value differs), missing (invault but absent from .env), extra (in .env but absent from vault). Values areread internally to classify but never written to stdout — only names appear inoutput, so the command is safe to pipe into review tooling.Exampleshasp secret diff .envhasp secret diff config/.env.production --json
hasp secret expose
hasp secret exposeExpose one vault item to one repo boundary and create the repo-scoped referencethat brokered commands use.Use expose when a repo needs a secret by reference, not by raw value.Flags--project-root <path> repo root to bind the secret to--json emit machine-readable result on stdoutExampleshasp secret expose OPENAI_API_KEY --project-root .hasp secret expose OPENAI_API_KEY --project-root . --json
hasp secret hide
hasp secret hideRemove 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 stdoutExampleshasp secret hide OPENAI_API_KEY --project-root .hasp secret hide OPENAI_API_KEY --project-root . --json
hasp app
hasp appConnect a normal application to selected vault secrets.An app is machine-scoped by default. Add --project-root only when the appshould run inside a specific repo boundary.Subcommandsconnect save the app profile and optional launcherrun run the saved app command through HASPinstall create or refresh the launchershell open a shell with the app bindings loadeddisconnect remove the app profile and managed launcherlist list saved appsLearn morehasp help app connecthasp help app run
hasp app connect
hasp app connectSave an app profile that maps vault secrets to env vars, temporary files, or atemporary dotenv bundle.When the repo manifest declares a target, --target can seed the app command andenv/file mappings into the local app profile. The saved profile remains localstate 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 itsdirectory is not on PATH, HASP can also patch your shell config, but only afteryou 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 resolvesduring 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 stdoutExampleshasp app connect myapp --cmd 'python app.py' --env OPENAI_API_KEY=@OPENAI_API_KEYhasp app connect myapp --cmd 'python app.py' --env OPENAI_API_KEY=@OPENAI_API_KEY --install=always --add-to-path=alwayshasp app connect web --project-root . --cmd 'npm run dev' --dotenv DATABASE_URL=@DATABASE_URL --dotenv-env ENV_FILEhasp app connect web --project-root . --target server.dev
hasp app run
hasp app runRun the saved app command through HASP. Extra args after the app name areforwarded to the saved command.Exampleshasp app run myapphasp app run myapp --port 3000
hasp app install
hasp app installCreate or refresh the managed launcher for a saved app.Use this when you skipped launcher creation during connect or when the launcherpath changed.Flags--json emit machine-readable result on stdoutExampleshasp app install myapphasp app install myapp --add-to-path=always
hasp app shell
hasp app shellOpen a login shell with the app bindings loaded. Extra args are forwarded tothe shell command.Exampleshasp app shell myapp
hasp app disconnect
hasp app disconnectRemove the saved app profile. If HASP manages the launcher path, it removes thelauncher too.Flags--json emit machine-readable result on stdoutExampleshasp app disconnect myapphasp app disconnect myapp --json
hasp app list
hasp app listList saved apps.Flags--json emit machine-readable list on stdoutExampleshasp app listhasp app list --json
hasp agent
hasp agentConnect a coding agent to HASP once, then let it pull secrets through the MCPsurface or the local config HASP writes.Agents are usually repo-scoped. Pass --project-root when you want HASP tobind the integration to one repo boundary.Subcommandsconnect write the agent config and save the agent recordmcp run the agent-specific HASP MCP wrapperlaunch run a command under an agent-safe HASP sessionshell open a shell under an agent-safe HASP sessiondisconnect remove the agent config block and the saved agentlist list saved agentslist-supported list shipped/generic profile support proofLearn morehasp help agent connecthasp help agent mcphasp help agent launchhasp help agent shell
hasp agent connect
hasp agent connectWrite the local agent config needed for HASP integration and save the agentas a managed entry. Generated HASP MCP configs now point at a managed localwrapper instead of a raw `hasp mcp` command so HASP can bind theagent process tree to a protected session automatically.Flags--project-root <path> repo root to bind the agent to (optional)--json emit machine-readable result on stdoutExampleshasp agent connect claude-code --project-root .hasp agent connect codex-cli --project-root .
hasp agent mcp
hasp agent mcpRun the agent-specific HASP MCP wrapper. This opens an agent-safe session forthe saved agent, registers the parent agent process with the daemon, and thenserves MCP on stdin/stdout.Use this as the generated config path instead of raw `hasp mcp` forfirst-class agent profiles.Exampleshasp agent mcp claude-codehasp agent mcp codex-cli
hasp agent launch
hasp agent launchRun a command under an agent-safe HASP session so subprocesses inheritHASP_AGENT_SAFE_MODE and HASP_SESSION_TOKEN.Use this when you want the whole agent process tree, not just the HASP MCPserver, to stay inside the protected policy context.Exampleshasp agent launch claude-code -- claudehasp agent launch codex-cli -- codex --model gpt-5.4
hasp agent shell
hasp agent shellOpen a shell under an agent-safe HASP session so anything launched from thatshell inherits HASP_AGENT_SAFE_MODE and HASP_SESSION_TOKEN.Exampleshasp agent shell claude-codehasp agent shell codex-cli -c 'env | grep HASP_'
hasp agent disconnect
hasp agent disconnectRemove the HASP config block for one saved agent and delete the saved record.Flags--json emit machine-readable result on stdoutExampleshasp agent disconnect claude-codehasp agent disconnect claude-code --json
hasp agent list
hasp agent listList saved agents.Flags--json emit machine-readable list on stdoutExampleshasp agent listhasp agent list --json
hasp agent list-supported
hasp agent list-supportedList shipped and generic-compatible support profiles with docs, release-gate,eval, benchmark, and connection proof.Exampleshasp agent list-supportedhasp agent list-supported --json
hasp project
hasp projectManage repo boundaries. Projects are where HASP applies guardrails, alias maps,and leak detection.Subcommandsadopt scan a directory tree and bind matching git reposbind bind one repo and create its initial alias mapdoctor audit manifest-backed project-target setup without exposing valuesexamples check or write placeholder example files from the manifestrequirements list manifest requirements, optionally filtered by targetstatus inspect one bound repotargets list manifest targets without command argvunbind remove one repo bindingCommon 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 committingproject 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 examples flags--target <name> limit check/write to one manifest target--check report stale or missing generated examples--write write missing/stale generated examplesExampleshasp project bind --project-root .hasp project requirements --project-root .hasp project targets --project-root . --jsonhasp project examples --project-root . --target server.dev --checkhasp project doctor --project-root . --jsonhasp project status --project-root .hasp project adopt --under ~/Workhasp project adopt --under ~/Work --previewhasp project unbind --project-root .
hasp run
hasp runRun 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. Useapp 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 ofopening 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 beforeexecuting (output goes to stderr)--dry-run print the decision tree and exit withoutexecuting (use with --explain)--explain-format <fmt> text (default) or jsonExampleshasp run --project-root . --env OPENAI_API_KEY=@OPENAI_API_KEY -- npm testhasp run --project-root . --target server.dev --grant-project window --grant-secret sessionhasp 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 injectResolve repo-scoped refs into env vars or temporary files for one command.Use inject for low-level brokered execution. Saved apps (hasp app run) arethe simpler path for repeatable non-repo apps.Authorization preview--explain print the resolved decision tree (project lease, secretgrant, grant window, redactor) before executing.--explain --dry-run print the decision tree and exit without executing.Exampleshasp inject --project-root . --file GOOGLE_APPLICATION_CREDENTIALS=@GOOGLE_APPLICATION_CREDENTIALS -- gcloud auth listhasp inject --project-root . --target release.sign -- ./deploy.sh
hasp write-env
hasp write-envWrite 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 aresafer 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 blockinside an existing file idempotentlyExampleshasp write-env --project-root . --output .env.local --env OPENAI_API_KEY=@OPENAI_API_KEYhasp write-env --project-root . --target build.config --grant-convenience windowhasp write-env --project-root . --output .env.local --env OPENAI_API_KEY=@OPENAI_API_KEY --forcehasp write-env --project-root . --output .env.local --env OPENAI_API_KEY=@OPENAI_API_KEY --append
hasp check-repo
hasp check-repoScan 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--allow-managed-secrets suppress exit-1 even when managed values are found(useful in CI scenarios that treat the scan asadvisory only)Exampleshasp check-repo --project-root .hasp check-repo --project-root . --json
hasp proof
hasp proofRun the brokered first-proof check. Verifies that the named secret is boundto the project and reachable through the broker's normal run flow, thenreports PASS / FAIL on stdout (and propagates exit code).This collapses the long quickstart one-linerhasp 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_PROOFOptional--project-root <path> defaults to the current directoryExampleshasp proof --secret api_tokenhasp proof --project-root /path/to/repo --secret secret_01
hasp daemon
hasp daemonManage the local runtime daemon.Subcommandsserve run the daemon in the foregroundstart start it in the backgroundstop stop itstatus inspect itExampleshasp daemon status
hasp session
hasp sessionWork with broker sessions directly.Subcommandsopen open a session for one repo boundarylist list active broker sessions (--mine restricts to the calling user)grant-plaintext grant one-time plaintext reveal/copy for a protected sessionresolve inspect an existing tokenrevoke revoke an existing tokenCommon flags--json emit machine-readable result on stdoutsession 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 usersession resolve / revoke flags--token <token> session token to inspect or revoke--all revoke all active sessions (revoke only; exclusive with--token)Exampleshasp session open --host-label local-cli --project-root .hasp session list --minehasp session resolve --token $HASP_SESSION_TOKENhasp session revoke --token $HASP_SESSION_TOKENhasp session revoke --all
hasp session grant-plaintext
hasp session grant-plaintextGrant 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 interactiveand local, and plaintext grants stay one-time, item-scoped, action-scoped, andshort-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 stdoutExampleshasp session grant-plaintext --token $HASP_SESSION_TOKEN --item OPENAI_API_KEY --action reveal --grant-window 60shasp session grant-plaintext --token $HASP_SESSION_TOKEN --item OPENAI_API_KEY --action copy --grant-window 60s
hasp vault
hasp vaultManage local vault/session material.Subcommandslock revoke active sessions and grants AND forget the saved keychain unlockforget-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 keyCommon flags--json emit machine-readable result on stdout (lock, forget-device, rekdf)Exampleshasp vault lockhasp vault forget-devicehasp vault rekdfhasp vault rekdf --jsonHASP_MASTER_PASSWORD=old HASP_NEW_MASTER_PASSWORD=new hasp vault rekey
hasp vault lock
hasp vault lockRevoke active daemon sessions and local grant material, AND forget the savedkeychain (convenience) unlock — clearing the envelope's ConvenienceWrap anddeleting the keychain item. This does not rotate provider credentials.Use this as the "walking-away-from-the-machine" big red button: next time thevault opens, a same-uid attacker cannot replay a stored keychain key, andevery in-flight grant and session is gone.Exampleshasp vault lockhasp vault lock --json
hasp vault forget-device
hasp vault forget-deviceForget 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 nolonger revive the vault without the master password.2. Delete the keychain item so a same-uid attacker cannot read the wrappedkey off disk and replay it.This is narrower than `hasp vault lock` — it leaves active daemonsessions and grant material alone. Use it when you want to revoke the "stayunlocked 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.Exampleshasp vault forget-devicehasp vault forget-device --json
hasp vault rekey
hasp vault rekeyRotate the master password that protects the vault. The underlying vault key(and therefore every sealed item) is preserved — only the password wrap isre-derived under the new password. Use this when the master password may havebeen observed or simply on a regular cadence.Both passwords are read from the environment so they never touch shell historyor argv:HASP_MASTER_PASSWORD current master passwordHASP_NEW_MASTER_PASSWORD new master password to installSide effects (atomic with the password rotation):- Clears the saved convenience-unlock wrap (you must re-enable it afterrekey if you still want keychain-backed unlock on this device).- Writes a single audit event of type `rekey`; password values arenever recorded.The old password no longer unlocks the vault after the call returns.ExamplesHASP_MASTER_PASSWORD=$old HASP_NEW_MASTER_PASSWORD=$new hasp vault rekeyHASP_MASTER_PASSWORD=$old HASP_NEW_MASTER_PASSWORD=$new hasp vault rekey --json
hasp status
hasp statusShow local daemon and vault status.Exampleshasp statushasp status --json
hasp ping
hasp pingCheck whether the local daemon can answer requests.Flags--json emit machine-readable result on stdoutExampleshasp pinghasp ping --json
hasp audit
hasp auditPrint the local audit log.Subcommandstail print the most recent events; -f streams new appendsverify verify the local audit chain HMAC and exitFlags--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 forthe 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 orGo duration (e.g. 1h)Exampleshasp audithasp audit --incident-bundle --jsonhasp audit tail -n 20 -f
hasp audit tail
hasp audit tailPrint the most recent audit events. With --follow, keep streaming new appendsuntil 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 eventsExampleshasp audit tailhasp audit tail -n 20 -fhasp audit tail --all --since 1hhasp audit tail -f --json --action secret.get.plaintext_blocked
hasp export-backup
hasp export-backupWrite an encrypted backup for the local vault.Flags--output <path> destination file for the encrypted backup--recovery-passphrase <pp> passphrase protecting the backup (prefer stdinor 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 stdoutThe passphrase may also be supplied via the HASP_BACKUP_PASSPHRASE environmentvariable. Passing it directly on the command line is not allowed.Examplesecho "$PP" | hasp export-backup --output backup.json --recovery-passphrase-stdinhasp 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-backupRestore 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 atruntime; use HASP_MASTER_PASSWORD instead)--json emit machine-readable result on stdoutThe passphrase may also be supplied via HASP_BACKUP_PASSPHRASE. The masterpassword must be provided via HASP_MASTER_PASSWORD. Passing secrets directlyon the command line is not allowed.Examplesecho "$PP" | hasp restore-backup --input backup.json --recovery-passphrase-stdinhasp restore-backup --input backup.json --recovery-passphrase-fd 3 3<<<"$PP"
hasp mcp
hasp mcpStart the MCP server on stdin and stdout.Use this from agent configs, not by hand, unless you are debugging the MCPtransport.Exampleshasp mcp
hasp tui
hasp tuiDeprecated. `hasp tui` does not open a real terminal UI; it prints aone-shot key/value snapshot of the current project binding (canonical root,visible refs, vault item count) and exits. The name was aspirational and iskept 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` willprint 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)Exampleshasp project status # recommended replacementhasp tui # legacy snapshot (prints deprecation warning)hasp tui --json # legacy snapshot as JSON
hasp version
hasp versionPrint the build version.Flags--json emit machine-readable version envelope on stdoutExampleshasp versionhasp version --json
hasp completion
hasp completionEmit a shell completion script for bash, zsh, fish, or powershell on stdout.The completable commands are derived from the live command inventory so thescript never lags the dispatcher.Exampleshasp completion bash >> ~/.bashrchasp completion zsh > ~/.config/zsh/_hasphasp completion fish > ~/.config/fish/completions/hasp.fishhasp completion powershell | Out-String | Invoke-Expression
hasp upgrade
hasp upgradeDownload a newer signed hasp release and atomically replace the runningbinary. Verification chain (fail-closed at every step):1. The release ships a KEYS file listing currently-trusted Ed25519public 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 untilthis 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 stdoutExampleshasp upgrade --version v0.2.0hasp upgrade --version v0.2.0 --yeshasp upgrade --version v0.2.0 --json --yesFind releases at https://github.com/gethasp/hasp/releases.
hasp docs
hasp docsRender reference documentation from the live help topic inventory. Useful forshipping a single offline reference page alongside the binary and fordownstream packagers who want the same source of truth as the CLI.Subcommandsmarkdown render every help topic as one markdown pageExampleshasp docs markdown --out docs/cli.md
hasp internals
hasp help internalsLower-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 secretsvault 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 acommand see "API_TOKEN" while the vault stores "stripe_live".reference a structured pointer to a vault item ("@my_secret") thatresolves 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 beinjected into env, written to a file, or held vault-only.Repo (project) surfaceproject 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 secretcan flow to multiple consumers under different aliases.Broker and grantsbroker 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 forone open session. Never written to disk; binds to a peer PID.Redactor encoding coverageThe redactor scans output for every encoded form of each managed secret.Encoding forms currently masked (minRedactLen=6 bytes minimum value length):raw literal bytesbase64-std RFC 4648 standard alphabet with paddingbase64-url URL-safe alphabet with paddingbase32-std RFC 4648 standard alphabet with paddinghex-lower lowercase hex (0-9, a-f)hex-upper uppercase hex (0-9, A-F)url-encoded percent-encoded query-string formjson-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 formMarkers 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 verificationaudit 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 isdelivered.Exampleshasp help granthasp audit tail --jsonhasp doctor
hasp exit-codes
hasp help exit-codesEvery hasp command exits with a stable bucket so scripts can branch onmachine-readable failure without parsing strings. The same buckets back the"code" field in --json error envelopes.0 ok command succeeded1 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)Exampleshasp secret show DOES_NOT_EXIST # exits 6 (E_NOT_FOUND)hasp secret show ANY --json # exits 3 if vault is lockedhasp check-repo --project-root . # exits 5 if a managed value is on diskScripts should branch on the bucket, not the message text:hasp secret show "$NAME" >/dev/nullcase $? in0) echo "ok" ;;6) echo "not found" ;;3) echo "vault locked or grant denied" ;;*) echo "other error: $?" ;;esac