Repository navigation
zn-gate 1.9.1
zn-gate 1.9.1 finds more kinds of secrets with zn-gate scan and says what to do about each one, gives repairs that work in zn-gate check and zn-gate init (also after a Node.js version is removed), and closes ways an AI agent could start the guided zn-gate init. It also stops clearly on Node.js older than 18. Update with npm install -g zn-gate@1.9.1 and pip install -U zn-gate.
If a CI job runs zn-gate scan: the Node.js scan now reports more secret types, so a job that fails on findings can start failing on files that passed before. If you use the agent hooks: a prompt that holds an opaque Authorization: Bearer token is now blocked, and one in a tool's output is replaced.
Added
zn-gate scanfinds more secrets, in Node.js and Python alike: values of--api-key=,--password=,--token=,--secret=and similar flags on a command line; quoted values assigned to a name that ends in password, secret, token or api key with=,:,:=or=>(also$password = "..."), when the value looks machine-generated; an opaqueAuthorization: Bearertoken; and the password inhttps://user:password@hostandssh://user:password@hostURLs, such as git remotes. A flag without a value, a reference ($TOKEN,${API_KEY}), a placeholder (<token>,changeme) and a URL without a password are not reported. The Node.js scan now also reports the provider token formats the Python scan already reported (Slack, Stripe, Google, Hugging Face and the others the scrubber knows), with the same rule names.zn-gate scanreads UTF-16 files that start with a byte order mark, and the private key filesid_xmssandidentity.- The scrubber also replaces an opaque
Authorization: Bearertoken (new typeBEARER_TOKEN), as the Python package already did; zn's own__ZN_<NAME>__markers are left alone. GitHub's fixedx-oauth-basicpassword (https://<token>:x-oauth-basic@host) is no longer a URL password in either package; the token in the user part is still found by its own pattern. A password that is only a reference (%NAME%,$NAME,${NAME},<name>,{{name}}) is not one either, while a literal password is redacted whatever the user part says.RULES_VERSIONis now2026-10-16.4andSCRUB_RULES_VERSION2026-10-16.3.
Changed
- With Node.js older than 18, the
zn-gateandzncommands you run stop with a short message that names the version and how to install Node.js 18 or later (exit code 1). Hooks, MCP servers and thezn runcommands that zn's hooks write keep running and print a warning, so a check that works today is not turned off. Node.js 16 and 17 were never supported; some commands happened to run on them. - The Python
zn-gatesays that commands such ashooks,init,checkandunlockare in the npm package and givesnpx -y zn-gate init, instead of argparse's "invalid choice" error. zn-gate check: when a hook cannot start because its Node.js or its zn-gate files are gone (for example afternvm uninstall), the fix it gives is a freshnpm install -g zn-gateand thenzn hooks install <agent>, since the old Node.js took itsznwith it. Claude Code set up withzn hooks installis told to run that again rather than to install the plugin. The zn-gate plugin together with the hooks ofzn hooks install claude-codeis reported as not protected, because both run and a broken one can block every prompt; the fix iszn hooks uninstall claude-code. A zn-gate plugin that is turned off is fixed withclaude plugin enable zn-gate@usezn; next to zn's own hooks, which then are the ones that protect Claude Code, it is only noted.zn-gate initfollows the same routes. A Claude Code prompt hook withoutonFailure: "block"gets a note.- The Python source distribution is now reproducible: two builds of the same commit with the same build tools give the same file, byte for byte, as the wheel and the npm tarball already did. CI and the release workflow build it twice and fail if the two differ.
zn-gate scansays "Secret found" for a secret, instead of calling it a threat, and adds one next step in plain words: runnpx -y zn-gate env shadow <file>to move the values of a.envfile into the local vault (the file name is shown only when it is made of plain characters and does not start with-, otherwise the command says<file>), runnpx -y zn-gate secret set NAMEto store any other value, move a private key out of the file, and rotate anything that was ever committed or shared. The value is never printed. In--format github, a secret's annotation is titledSecret found (<rule>)and its message is the next step; the summary line readsFound N secrets and M security threats.In--format json, each secret has a newnext_stepfield and the report has a newtotal_secretscount;total_threatsstill counts every finding and the other fields are unchanged. Injection findings keep their wording.- The Node.js scan reports more secret types than before (the provider formats, Bearer tokens, URL passwords, command-line flags and assignments above), so a CI job that fails on findings (
fail-on-threat, or the exit code ofzn-gate scan) can start failing on files that passed before. - Agent hooks (Node.js): a prompt that holds an opaque
Authorization: Bearertoken is now blocked, and one in the output of a tool or MCP call is replaced, as for the other secret formats the scrubber knows. Usezn secret set NAMEand the__ZN_NAME__marker in its place. - Docs: the Python install steps say that Debian and Ubuntu need the
python3-venvpackage forpython3 -m venv. - Docs: what to do when your agent blocks every prompt because zn's hook cannot run (usually after Node.js is upgraded or moved):
zn-gate check, reinstall, or turn zn off for that agent until it is fixed (docs/compat.md). - Docs: the README, docs/secrets.md and docs/check.md describe the 1.9.1 behaviour: "Secret found" and its next step in
zn-gate scan, the secret types it finds (and that a CI job can start failing on files that passed before), the Node.js 18 message, the repair steps ofzn-gate check, the guidedzn-gate initwithout arguments, andzn hooks uninstall claude-codekeeping othersecretsMCP servers.
Fixed
zn hooks uninstall claude-coderemoved any user MCP server calledsecretsfrom Claude Code, also one that was not zn's. It now removes only zn's own server, recognised by its exact command (zn-gate'ssecrets-mcp), and says so when it leaves another one in place.zn hooks installno longer overwrites anothersecretsserver that only mentionssecrets-mcp.- An AI agent could start the guided
zn-gate initdespite the rule that keeps agents from running it: with a backslash or other characters the shell joins into one word, an option in capital letters, ornpm exec, which keeps the options after the package for itself. These are refused now, and the guidedzn-gate initstops with an error when it gets any argument. An agent variable such asCLAUDECODEthat is set but empty now also counts as an agent.POLICY_RULES_VERSIONis2026-10-16.5.
How to verify these files: docs/verify-release.md