hushsecrets your AI agent can use but never readGitHub

What the agent may run

hush install-skill            # this project
hush install-skill --global   # every project

Installs a skill telling your agent never to ask for a pasted key, to use hush_run rather than reading values, and how to pick a set when you name one. It goes where each agent looks for instructions — the right-hand column of the table in Connecting your agent. Codex, Gemini CLI and Zed share .agents/skills/ (and ~/.agents/skills/ for --global), so one file serves all three. Without it the tools still work — the tool descriptions explain themselves — you just have to say so each time.

.hush/policy.json controls what it may run — through the MCP tools and through the CLI, so an agent that shells out to hush run or hush export meets the same approval prompt. For the agent's tools, anything that exists to dump or re-encode the environment is denied outright — shells, env, base64, curl, and every interpreter, because node -e can write the whole environment to a file that output redaction never sees. In your terminal the same commands are not refused: hush node server.js goes to the approval prompt with a warning line, the way op run asks rather than blocks. allowCommands still narrows both:

{
  "allowCommands": [],
  "denyCommands": ["your-own-additions"],
  "unsafeAllowCommands": [],
  "allowEnvs": ["default", "work-fal"],
  "allowHosts": ["api.stripe.com", "*.github.com"],
  "denyKeys": ["STRIPE_LIVE_KEY"],
  "maxRunMs": 120000,
  "approvalScope": "command"
}

Your floor. policy.json is a file in the repo, so an agent with write access can edit it. ~/.hush/policy.json — same shape, outside every repo — is your floor: a repo's policy can only tighten relative to it. allowCommands, allowEnvs and allowHosts can only narrow, requireApproval and denyKeys can only grow, biometry and approvalScope can only get stricter, and unsafeAllowCommands only takes effect when your floor lists the same command — the repo asks, you permit. unmaskKeys is floor-only as well: it is the list of keys you have allowed to print unmasked, and a repository cannot add to it. hush doctor shows every place a repo policy tried to go below your floor.

An allow list your floor sets keeps applying even when a repo's policy.json does not mention it. A repo file that omits allowCommands inherits your floor's list rather than replacing it with "no restriction"; a repo file that names only entries outside your floor is ignored as a whole. Both cases are reported by hush doctor, so a floor that is doing nothing is never silent.