Skip to content

mrz1836/hush

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

143 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

🀫  hush

Discord-gated secrets broker for AI agents

One passphrase. No key files. No dotfiles on agent disks.


Release Go Version License


CI / CD Β Β  Build Last Commit Β Β Β Β  Quality Β Β  Go Report Coverage
Security Β Β  Scorecard Security Β Β Β Β  Community Β Β  Contributors Bitcoin


Project Navigation

πŸš€Β Installation ⚑ QuickΒ Start πŸ“šΒ Documentation
πŸ”Β Security πŸ› οΈΒ CodeΒ Standards πŸ§ͺΒ ExamplesΒ &Β Tests
πŸ€–Β AIΒ Usage βš–οΈΒ License 🀝 Contributing
πŸ‘₯Β Maintainers

hush is a single Go binary that keeps every API key, OAuth token, and service credential encrypted on a single trusted host. Agents request short-lived, scoped sessions over Tailscale; the request is approved on your phone via Discord; approved secrets are delivered ECIES-encrypted end-to-end and injected into the agent process's environment β€” never written to disk on the agent machine.

If your dev workflow runs untrusted code (npm/pip packages, LLM-generated scripts, AI-agent tools that execute shell commands) and your secrets currently live in shell rc files or cloud-provider credential files, hush is for you. Vault, 1Password CLI, and dotfile-based env vars all leave files on disk that commodity malware grep for first. hush makes those files not exist.


                            TAILSCALE MESH
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚                                                                     β”‚
  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
  β”‚  β”‚  AGENT MACHINE           β”‚     β”‚  VAULT HOST                   β”‚ β”‚
  β”‚  β”‚  (untrusted, clean disk) β”‚     β”‚  (mlocked memory; offline)    β”‚ β”‚
  β”‚  β”‚                          β”‚     β”‚                               β”‚ β”‚
  β”‚  β”‚  interactive client /    β”‚     β”‚  vault server                 β”‚ β”‚
  β”‚  β”‚  supervisor              β”‚     β”‚                               β”‚ β”‚
  β”‚  β”‚       β”‚                  β”‚     β”‚       β–²                       β”‚ β”‚
  β”‚  β”‚       β”‚ ECDSA-signed     │─────┼──────►│ verify signature      β”‚ β”‚
  β”‚  β”‚       β”‚ claim            β”‚     β”‚       β”‚ check Tailscale IP    β”‚ β”‚
  β”‚  β”‚       β”‚                  β”‚     β”‚       β–Ό                       β”‚ β”‚
  β”‚  β”‚       β”‚                  β”‚     β”‚  Discord DM ─────► phone      β”‚ β”‚
  β”‚  β”‚       β”‚                  β”‚     β”‚       β”‚  [Approve]            β”‚ β”‚
  β”‚  β”‚       β”‚ ES256K JWT       │◄────┼──────── issue scoped JWT      β”‚ β”‚
  β”‚  β”‚       β”‚                  β”‚     β”‚       β–Ό                       β”‚ β”‚
  β”‚  β”‚       β”‚ secret fetch     │─────┼──────►│ ECIES-encrypt to      β”‚ β”‚
  β”‚  β”‚       β”‚ (ECIES bytes)    β”‚     β”‚       β”‚ ephemeral pubkey      β”‚ β”‚
  β”‚  β”‚       β–Ό                  β”‚     β”‚       β”‚                       β”‚ β”‚
  β”‚  β”‚  decrypt β†’ env var       β”‚     β”‚       └─────────────────────  β”‚ β”‚
  β”‚  β”‚  inject into child       β”‚     β”‚  [no key files anywhere]      β”‚ β”‚
  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
  β”‚                                                                     β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸš€ Installation

hush requires a supported release of Go (Go 1.26+) and is built CGO_ENABLED=0 β€” a single static binary.

Status: v0.1.0 is a private MVP. Treat the steps below as the documented happy path, not a guarantee.

Prerequisites: a vault host and an agent host on the same Tailscale tailnet, plus a Discord bot you control (https://discord.com/developers/applications) for the approval channel.

Build from source

git clone https://github.com/mrz1836/hush.git && cd hush
magex build && sudo install -m 0755 cmd/hush/hush /usr/local/bin/hush

⚑ Quick Start

Get up and running with these essential commands:


Run a confidence check

One command, fake secret, real Discord approval:

hush smoke --state-dir ~/.hush-smoke --reset

hush smoke walks the setup prompts, creates an isolated test vault, adds HUSH_SMOKE_TEST=hello-from-hush, starts a temporary Tailscale-only server, enrolls a client, asks you to approve in Discord, verifies the fake secret, and then shuts the temporary server down. Clean smoke artifacts safely with hush smoke clean (archives by default).


Bootstrap the vault host

hush init server          # guided / interactive; preflight + prompts
hush secret add OPENAI_API_KEY
hush serve                # binds Tailscale interface, brokers approvals

hush init server is the canonical first-run entry point. It runs a diagnostic-first preflight, prompts for the inputs it actually needs, classifies pre-existing state per-artifact, and never silently overwrites. When it asks for a listen address, use the vault host's Tailscale IPv4 plus a free port (for example, run printf '%s:7743\n' "$(tailscale ip -4)" on the server host). Do not use the laptop/client IP.

During hush init server, set discord_approval_channel_id if you want approvals in a Discord channel instead of owner DMs. On macOS, if the login Keychain is locked or unavailable, choose the env-token fallback and run hush serve with HUSH_DISCORD_BOT_TOKEN exported in that terminal.


Enrol the agent host

hush init client --machine-index 1
HUSH_SERVER="$(hush --config ~/.hush/config.toml server-url)"
hush request \
  --server "$HUSH_SERVER" \
  --machine-index 1 --scope OPENAI_API_KEY \
  --max-uses 1 --ttl 5m --reason "smoke test" \
  --exec printenv -- OPENAI_API_KEY

Approve on Discord; the child process you named in --exec runs with OPENAI_API_KEY in its environment β€” and only there. --exec names a program, not a shell string; pass child arguments after --. Nothing is written to disk on the agent host.


πŸ“– For the full walkthrough β€” Keychain ACL recovery, clock-skew override, --non-interactive mode β€” see docs/OPERATIONS.md. For Keychain vs HUSH_DISCORD_BOT_TOKEN positioning and the threat model, see docs/SECURITY.md Β§2.4. For long-running daemons, see docs/DAEMONS.md and deploy/examples/supervisors/. For server + supervisor TOML schemas, see docs/CONFIG-SCHEMA.md.


At a glance

What hush does:

  • Keeps every secret encrypted in a single AES-256-GCM + Argon2id (256MB) vault file on one trusted host.
  • Requires phone approval (Discord DM with interactive buttons) for every fresh session.
  • Delivers secrets ECIES-encrypted end-to-end into agent process memory only β€” no disk writes on the agent.

What hush explicitly does NOT do (v0.1.0):

  • No multi-owner approvals (a single configured operator approves; multi-owner is post-v0.1.0 future scope).
  • No cloud KMS / SaaS dependency. The vault is self-hosted and offline-capable.
  • No public network exposure. The vault server is bound to a Tailscale interface and refuses to start otherwise.

Why hush exists

When untrusted code lands on a developer machine β€” via npm/pip supply-chain attacks, LLM-generated scripts, or trojans masquerading as tools β€” the very first thing it does is enumerate known credential patterns in known files: shell rc files, cloud-provider credential files, .env files, signing keys, and PEM files.

hush exists to make this enumeration return nothing. Secrets stay encrypted on a single trusted host. Agents fetch them only after a human approves the request from a phone. Approved secrets are delivered into process memory and zeroed when the process exits. Nothing on disk.

For the full threat model, see docs/SECURITY.md.


Architecture summary

hush is a single Go binary playing three roles:

  • Vault server β€” holds the encrypted vault file in mlocked memory; issues ES256K-signed JWTs after Discord approval; ECIES-encrypts secret responses to the client's per-session ephemeral public key; exposes a tiny HTTP API over Tailscale only.
  • Interactive client β€” ECDSA-signs a claim with a per-machine BIP32-derived key; receives a JWT after approval; fetches and decrypts secrets; injects them into a child process's environment.
  • Supervisor β€” long-lived per-daemon process that holds the JWT and ephemeral ECIES key in mlocked memory across child crashes/restarts within the session TTL; runs validators before child start; exposes a Unix status socket for agent-visible freshness queries.

Seven security layers stack independently β€” compromise of any single layer does not enable secret extraction:

  1. BIP32 HD key hierarchy β€” all keys derived at runtime from a single passphrase. Zero key files on disk.
  2. ES256K asymmetric JWT signing β€” only the server can sign; leaking the public key does not enable forgery.
  3. ECIES end-to-end secret transport β€” secrets are encrypted to a per-session ephemeral pubkey; captured HTTP traffic shows binary blobs.
  4. ECDSA-signed client requests β€” every claim and revocation is signed with a registered per-machine client key.
  5. mlocked secure memory β€” SecureBytes containers; secrets never stored as Go string; explicit zeroing on shutdown.
  6. Signed hash-chained audit log β€” every event ECDSA-signed; chain breaks on modification.
  7. Obscurity β€” random API path prefix, custom vault file format, non-obvious binary name. Additive only β€” never load-bearing.

The network perimeter is Tailscale-only (Constitution Principle VI). Tailscale is the v0.1.0 mesh-VPN choice; the architecture does not depend on it specifically β€” the requirement is "no public reachability" and Tailscale satisfies it cleanly. The Approver interface is also pluggable; Discord is the v0.1.0 reference implementation and the only one that ships, but future Slack / Telegram / PagerDuty backends can be wired without changing the rest of the system.

For the full architecture treatment, see docs/ARCHITECTURE.md.


Tech stack

  • Go 1.26+ β€” single static binary, CGO_ENABLED=0 exclusively (Constitution Principle IX).
  • decred/dcrd/dcrec/secp256k1/v4 β€” secp256k1 primitives used for ECDSA signing, ES256K JWTs, and ECIES envelope encryption (Constitution Principle III).
  • decred/dcrd/hdkeychain/v3 β€” BIP32 HD key derivation from the operator passphrase (Constitution Principle III); paired with stdlib golang.org/x/crypto/argon2 for the KDF.
  • Tailscale β€” the only network reachable to the vault server. WireGuard underneath; identity-based ACLs above.
  • Discord + discordgo β€” phone-based approval channel; the v0.1.0 reference Approver.
  • golang-jwt/jwt v5 β€” JWT framework; hush registers a custom ES256K signing method.
  • go-toml v2 β€” strict TOML parsing for server and supervisor configs.
  • zalando/go-keyring β€” OS keychain access with ACL support.
  • cobra + pflag β€” CLI subcommand routing and flag parsing.

The SecureBytes mlock pattern is custom-implemented in internal/vault/securebytes/; the design is inspired by sigil but takes no dependency on it.


πŸ“š Documentation

View the comprehensive documentation for hush:

Doc Purpose
docs/OPERATIONS.md Setup, day-to-day modes, --non-interactive, Keychain recovery
docs/ARCHITECTURE.md Component model, trust boundaries, supervisor lifecycle
docs/SECURITY.md Threat model, 7 security layers, residual risks
docs/CONFIG-SCHEMA.md Server + supervisor TOML schemas, defaults, validation
docs/DAEMONS.md Supervisor pattern, refresh tuning, validator authoring
docs/API.md HTTP endpoint reference
docs/LIFECYCLE-SCENARIOS.md 17 supervisor lifecycle scenarios β€” behavioral reference
docs/TAILSCALE-ACLS.md Recommended ACL pattern restricting the vault port
docs/CLEAN-MACHINE.md Agent-machine cleanup checklist
.specify/memory/constitution.md The 11 non-negotiable principles

Goals

The v0.1.0 goal is a working private MVP that proves the threat model in practice: an agent machine with a clean disk, a vault host on a phone-gated Tailscale mesh, and a daily dev workflow that no longer requires plaintext credentials anywhere on the agent.

Post-v0.1.0 / future scope (any of these may become a future release; none is on the v0.1.0 critical path):

  • Multi-owner approvals
  • Slack / Telegram / PagerDuty Approver backends (the interface is already pluggable)
  • Shamir passphrase splitting (sigil's SSS) for vault recovery
  • Web dashboard
  • Proxy mode (vault proxying provider API calls instead of injecting tokens)
  • Agent-side credential proxy (per-provider HTTP proxy on the agent host)
  • TLS within Tailscale (defence-in-depth on top of WireGuard)
  • TOTP second factor on Discord approval
  • Custom validator authoring SDK

πŸ” Security

Important Disclaimer

⚠️ Experimental Software β€” Use at Your Own Risk

hush is experimental, open-source software provided "AS-IS" without warranty. By running it, you acknowledge:

  • Private MVP: v0.1.0 is an unproven private MVP β€” not production-grade, and the end-to-end round-trip has not been independently verified.
  • No formal audit: hush has not been professionally audited or penetration-tested.
  • You own the host: the trusted vault host, your Tailscale config, and your Discord bot are yours to secure β€” hush only does its part.
  • No liability: the authors accept no responsibility for compromised secrets, downtime, or damages.

Don't trust hush with a secret you can't afford to rotate. If it breaks, you get to keep both pieces.

For the full threat model and the 7 security layers, see docs/SECURITY.md. For security issues, see our Security Policy or contact: hush@mrz1818.com.


Additional Documentation & Repository Management

Development Setup (Getting Started)

Install MAGE-X build tool for development:

# Install MAGE-X for development and building
go install github.com/magefile/mage@latest
go install github.com/mrz1836/go-mage/magex@latest
magex update:install
Build Commands

View all build commands:

magex help

Common commands:

  • magex build β€” Build the binary
  • magex test β€” Run test suite
  • magex lint β€” Run all linters
  • magex deps:update β€” Update dependencies
Binary Deployment

This project uses goreleaser for streamlined binary deployment to GitHub. To get started, install it via:

brew install goreleaser

The release process is defined in the .goreleaser.yml configuration file. Then create and push a new Git tag using:

magex version:bump bump=patch push=true branch=master

This process ensures consistent, repeatable releases with properly versioned artifacts.

GitHub Workflows

hush uses the Fortress workflow system for comprehensive CI/CD:

  • fortress-test-suite.yml β€” Complete test suite across multiple Go versions
  • fortress-code-quality.yml β€” Code quality checks (gofmt, golangci-lint, staticcheck)
  • fortress-security-scans.yml β€” Security vulnerability scanning
  • fortress-coverage.yml β€” Code coverage reporting to Codecov
  • fortress-release.yml β€” Automated binary releases via GoReleaser

See all workflows in .github/workflows/.

Updating Dependencies

To update all dependencies (Go modules, linters, and related tools), run:

magex deps:update

This command ensures all dependencies are brought up to date in a single step, including Go modules and any managed tools. It is the recommended way to keep your development environment and CI in sync with the latest versions.


πŸ§ͺ Examples & Tests

All unit tests run via GitHub Actions. View the configuration file.

Run all tests (fast):

magex test

Run all tests with race detector (slower):

magex test:race

Test Coverage

View coverage report:

magex test:coverage

Coverage reports are automatically uploaded to Codecov on every commit.


πŸ› οΈ Code Standards

Read more about this Go project's code standards.


πŸ€– AI Usage & Assistant Guidelines

Read the AI Usage & Assistant Guidelines for details on how AI is used in this project and how to interact with AI assistants.


πŸ‘₯ Maintainers

MrZ
MrZ

🀝 Contributing

View the contributing guidelines and please follow the code of conduct.

How can I help?

All kinds of contributions are welcome πŸ™Œ! The most basic way to show your support is to star 🌟 the project, or to raise issues πŸ’¬. You can also support this project by becoming a sponsor on GitHub πŸ‘ or by making a bitcoin donation to ensure this journey continues indefinitely! πŸš€

Stars


πŸ“ License

License

This project is licensed under the terms of the LICENSE file at the repo root.

About

🀫 Discord-gated secrets broker for AI agents β€” encrypted vault, JWT sessions, Tailscale-only

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors