zn-gate 1.4.1 and what leaves your machine
We promise that secrets and personal data never leave your machine. For users of zn-gate 1.4.0 who had set ZN_API_KEY, that promise was not true. This post explains what the package did, what our API stored, what we changed in 1.4.1 and what you should do. The short version: upgrade, and if you ran 1.4.0 with an API key, rotate any credential that could have appeared in tool output.
What 1.4.0 did
zn-gate checks three kinds of text: prompts, tool-call arguments and tool results (the contents of files your agent reads, the output of commands it runs). All three were evaluated by the local rules first. In 1.4.0 and earlier, if the local rules did not block the text and ZN_API_KEY was set, the Node package then sent that text to api.usezn.com for a second opinion from the Galvanize-60M classifier. It did so without redacting secrets, and it did so for tool results and tool arguments, not only prompts.
The README said the package was local-first and that secret redaction was applied. The redaction function existed in the code, but no executable path called it. We found this during an internal review of the published package on 2026-10-11.
Who is affected:
- Users of the npm package (the MCP server,
zn-gate shield,zn-gate analyze,zn-gate testor the library) withZN_API_KEYset andZN_LOCAL_ONLYnot set totrue. - Users of the Python package with
ZN_API_KEYset: onlyanalyze()andzn-gate analyzesent text, without redaction.guard,check_tool_call,check_tool_result,sanitize_tool_resultand the framework integrations were always local. - Users who never set
ZN_API_KEY, or who setZN_LOCAL_ONLY=true, are not affected. Nothing left the machine.
What our API stored
The text travelled over TLS and was evaluated by the classifier. Two routes also stored the first 1,000 characters of each input in our evidence table, without an expiry: the legacy /prod/analyze route and the MCP analyze route. The current /v30/analyze route, which zn-gate uses by default, did not store input for paying tiers; it kept a redacted, truncated copy only for the free Contributor tier, which opts into that. Access logs record route and status only, never content.
On 2026-10-11 we changed the API to store only a SHA-256 hash and the length of the input, and we deleted the stored input text from the evidence table for every record that had it: 1,281 records, dated between August 22 and September 12, 2026.
What 1.4.1 changes
- Tool results, tool-call arguments and tool descriptions are evaluated only locally, under every configuration: MCP server,
shieldproxy and library. - The cloud is opt-in. Prompt analysis queries the cloud only if you set both
ZN_CLOUD=1andZN_API_KEY.ZN_API_KEYalone enables nothing.ZN_LOCAL_ONLY=truestill overrides everything. - Redaction runs on the real code path.
check_tool_resultalways returns content passed through the secret redactor;check_tool_callreturns sanitized arguments;shieldforwards tool output with secrets redacted. When the cloud is enabled, prompt text goes through the redactor before it is sent. zn-gate statusprints what your configuration sends, and the self-test never uses the network.- New tests mock the network and count requests: tool output with fake secrets comes back redacted and makes zero requests, even with
ZN_API_KEYandZN_CLOUD=1set. Against the 1.4.0 code, seven of those eight tests fail.
The README now has a "What leaves your machine" table in all three packages, and the same table is on this site.
What to do
- Upgrade:
npx -y zn-gate@latest(ornpm install -g zn-gate@1.4.1) andpip install -U zn-gate. - If you ran 1.4.0 or earlier with
ZN_API_KEYset, assume any credential that appeared in tool output or tool arguments during that time could have been transmitted, and rotate it. - Run
npx -y zn-gate statusto see what your configuration sends now.
The advisory is published on GitHub as GHSA-r4h2-qcf2-8227, with the full list of affected code paths in the 1.4.1 changelog.
Why we are writing this up
Nobody reported this to us; we found it ourselves. We could have shipped 1.4.1 with a one-line changelog entry. We are publishing the details because the whole point of zn-gate is that you can trust what it does with your data, and that trust has to survive the days when we get it wrong. If you have questions, or you think something here is still not precise enough, write to security@usezn.com.
— John Silver