hush-hush-cli

module
v1.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 3, 2026 License: GPL-3.0

README

hush-hush-cli

CI pkg.go.dev licence

Client for the hush-hush secrets object store — the writer's and every consumer's interface to it: inject a secret, fetch and decrypt one, rotate a value, delete an object.

Requirements

  • Go 1.27 or newer to build from source.
  • age, to generate the keypairs a writer and a consumer each need. Not a dependency of this CLI itself — it only ever handles already-sealed ciphertext, never a private key or plaintext value outside a single inject/get call.
  • A running hush-hush server to talk to.

Installation

See INSTALL.md - AUR, .deb/.rpm, Docker, go install, or from source.

Usage

A consumer needs an age keypair to receive a secret - age-keygen generates one:

age-keygen -o consumer.key
# Public key: age1...

Inject a secret, sealed to one or more recipients (a write token comes from hush-hush token issue on the server):

export HUSH_HUSH_SERVER=http://localhost:8080
export HUSH_HUSH_TOKEN=9f8e7d6c...

echo -n "hunter2" | hush-hush-cli inject mattermost_deploy_webhook \
  --recipients age1... --used-by homelab/vps-docker \
  --description "prod deploy webhook"

Fetch and decrypt it - only whoever holds a matching private key can. --identity takes the bare key, so pull it out of age-keygen's comment header first:

hush-hush-cli get mattermost_deploy_webhook --identity "$(tail -1 consumer.key)"

Rotate the value, then remove the object once nothing needs it any more:

echo -n "new-value" | hush-hush-cli update mattermost_deploy_webhook \
  --recipients age1...
hush-hush-cli delete mattermost_deploy_webhook

inject and update both read the new plaintext from stdin rather than a flag or argument, so it never ends up in shell history or a process listing.

Configuration

Settings are read in this order, each layer overriding the one before it: flags > environment variables > config file > defaults. None of them are required - environment variables alone are enough for a CI job or a container - but init writes a starter file the first time it matters:

hush-hush-cli init      # writes ~/.config/hush-hush-cli/config.yaml

($XDG_CONFIG_HOME instead of ~/.config if it's set.) Run the command with nothing configured yet - no config file, no relevant environment variable - on an interactive terminal, and it offers to write that starter file itself before continuing; --yes skips the prompt and writes it unconditionally, for a script that wants the file without a person to answer for it. --force on init itself overwrites an existing file, which the prompt never does.

Flag Environment variable config key Meaning
--server HUSH_HUSH_SERVER server Server base URL. Default http://localhost:8080.
--token HUSH_HUSH_TOKEN token Bearer token, for inject/update/delete.
--token-command HUSH_HUSH_TOKEN_COMMAND token_command Command whose trimmed stdout is the token instead - wins over --token if both are set.
--caller HUSH_HUSH_CALLER caller Self-presented identity recorded in the audit log. Optional.
--recipients HUSH_HUSH_RECIPIENTS recipients Comma-separated age recipients, for inject/update.
--identity HUSH_HUSH_IDENTITY identity Comma-separated age private keys, for get.
--used-by - - Consumers of the secret (repeatable or comma-separated), inject only.
--description - - Free-text label, fixed at creation, inject only.

Contributing

See CONTRIBUTING.md for the toolchain, the hooks, and how a change gets reviewed and released.

Licence

GPL-3.0.

Directories

Path Synopsis
cmd
hush-hush-cli command
Command hush-hush-cli is the client every hush-hush consumer speaks through - the writer's only interface to the service, and the same binary any consumer (CI job, deploy script) runs to fetch and decrypt a value locally.
Command hush-hush-cli is the client every hush-hush consumer speaks through - the writer's only interface to the service, and the same binary any consumer (CI job, deploy script) runs to fetch and decrypt a value locally.
internal
cli
Package cli implements every hush-hush CLI command as a plain function over Config, independent of cobra - the actual command definitions in cmd/hush-hush-cli are a thin parsing shell around these (rules/go.md: "Keep RunE a thin shell").
Package cli implements every hush-hush CLI command as a plain function over Config, independent of cobra - the actual command definitions in cmd/hush-hush-cli are a thin parsing shell around these (rules/go.md: "Keep RunE a thin shell").
cliconfig
Package cliconfig is the config-file convention every hush-hush binary follows (rules/cli.md): a YAML file under XDG_CONFIG_HOME that flags and environment variables both override, a starter an init command writes, and the interactive nudge to write one when nothing is configured yet.
Package cliconfig is the config-file convention every hush-hush binary follows (rules/cli.md): a YAML file under XDG_CONFIG_HOME that flags and environment variables both override, a starter an init command writes, and the interactive nudge to write one when nothing is configured yet.
client
Package client is the CLI's transport to the hush-hush server - a thin adapter over the generated hush-hush-go SDK, kept so internal/cli depends on this package's own sentinel errors and ObjectMetadata shape rather than the SDK's directly (design.md).
Package client is the CLI's transport to the hush-hush server - a thin adapter over the generated hush-hush-go SDK, kept so internal/cli depends on this package's own sentinel errors and ObjectMetadata shape rather than the SDK's directly (design.md).
seal
Package seal wraps age encryption for the writer's side of hush-hush: value in, ciphertext out, no server or CLI process ever holding a private key (openspec/changes/secrets-object-store/design.md).
Package seal wraps age encryption for the writer's side of hush-hush: value in, ciphertext out, no server or CLI process ever holding a private key (openspec/changes/secrets-object-store/design.md).
testserver
Package testserver is a small in-memory, stateful stand-in for the hush-hush server's HTTP API - internal/client's actual transport contract (api/openapi.yaml's /objects endpoints), not hush-hush's own internal/api implementation, which stays in that repo.
Package testserver is a small in-memory, stateful stand-in for the hush-hush server's HTTP API - internal/client's actual transport contract (api/openapi.yaml's /objects endpoints), not hush-hush's own internal/api implementation, which stays in that repo.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL