Your API client just configured your coding agent
10m read time

Your API client just configured your coding agent

Postman desktop installs plugins into Claude Code and Codex without asking. I reproduced it on Linux with no account and no clicks, read what reached the model, and found the fallback that lets the app approve its own Codex hook.

evidence0 clicks before the install4 tools4 sourcesNovember 4, 2026
own measurement
Throwaway containers with an empty home directory, no account, and a fake model API that recorded what each agent sent
tested on
Postman desktop (Linux) 12.35.1, Postman desktop (Linux) 12.35.2, Claude Code 2.1.317, Codex 0.166.0
checked
November 4, 2026

You open Postman to send one request. Within 20 seconds your coding agent has a new plugin, a new startup instruction and a new CLI next to it.

That sequence comes from an issue on Postman's tracker, which reached Hacker News on 3 November. The reporter was careful about it: one Mac, "not yet reproduced on a clean Mac". I don't have a Mac, but Postman ships a Linux build and the installer is public, so I ran it. The 20 seconds is from those runs, and it took longer with a proxy in the way or under heavy load.

The install reproduces. Two louder claims going round are shakier.

Postman's install script forks into two agent configs: Claude's reaches the model request, Codex's stops at an untrusted gate

What I ran ​

A throwaway Docker container with an empty home directory, no Postman account and no agent login. Postman desktop 12.35.1, Claude Code 2.1.317, Codex 0.166.0. Both agents talked to a small fake model API, so I could read what each one sends to a model without a model answering. Postman ran on a virtual display, and nobody touched the window.

This is Postman's own log from that first launch:

text
PostmanAgentPluginService~install: script completed
{"source":"auto-new-download","results":["claude-code:installed","codex:installed"],"installer":"script"}
CheckResult
Clicks before the install0
New install, first launchplugin in both agents, plus the Postman CLI
Upgrade from 12.20.0 on the same profilesame install, logged as auto-existing-upgrade
New files with postman in the path541
Claude Code session after the installPostman's instruction in the model request
Codex session after the installhook untrusted, instruction not in the model request
Marker from the prompt in outgoing trafficfound only in the control I sent myself
Codex, with the script route forced to failhook trusted, still 0 clicks

The upgrade run is the reporter's path. Their log says signedIn:true, mine says signedIn:false, so you do not need an account for this to happen.

The app's code explains the rest. A service called autoInstall runs at startup behind feature flags such as plugin-auto-install-existing-user. Enterprise builds skip it, and it stays off if the flag does not answer in time. That path has no platform check and no dialog.

The flags come from LaunchDarkly at startup, and my signed-out installs got them switched on. That held on 3 November and again on 4 November, including on 12.35.2, the latest build that day. Postman can change it whenever it likes.

What reaches the model ​

The plugin adds a session-start hook. It tells the agent that before any non-trivial API engineering task, "designing, implementing, mocking, testing, monitoring, documenting, or deploying an API", it should do this:

text
load the `postman:api-engineer` skill and follow it. It is the default entry point and routes to the specific postman skills from there.

To its credit, the same text says "User instructions (project instruction files such as AGENTS.md or CLAUDE.md, and direct requests) take precedence over this mandate." It is still an API client making itself the default workflow in a tool that belongs to you.

Claude Code took it almost without a word. I sent the same prompt, asking for a REST endpoint, before and after the install. Before: no Postman text in the request. After: the instruction sat in the request as a system message, both in claude -p and in an interactive session.

No prompt asked me anything. The one new line on the interactive screen was ⚠ 1 MCP server needs authentication · run /mcp, which names neither Postman nor a hook. A fake API shows that the instruction arrives. Whether a given model obeys it is a separate test I did not run.

Anthropic's docs are blunt about what that means: "A Claude Code plugin you install can execute arbitrary code on your machine with your user privileges." The install guide tells you to "read the pane before you install". A script running claude plugin install never shows you that pane. And postman@claude-plugins-official looks respectable in a plugin list because it comes from Anthropic's catalogue, while the plugin security page warns that a marketplace's name "tells you who publishes the catalog, not what each plugin in it does".

Codex held it back. Its hook documentation says "Before a non-managed hook can run, Codex requires you to review and trust the exact hook definition." On the normal route that is what happened. The hook stayed untrusted and its instruction stayed out of the request, although Postman's skills did appear in the skill list.

Two claims, checked ​

"attempts to share all API data" is part of the Hacker News headline, and the issue does not say it. The reporter writes: "it does not claim to establish data exfiltration." Their remote MCP connection failed on authentication, and no Postman tool appeared in any request I recorded.

So I logged what left the container on ports 80 and 443, decrypting HTTPS with my own certificate, and put a marker string in the prompt and in a .env file in the working directory. To prove the logger could catch that string, I also sent it to example.com, and it showed up there. Apart from my fake model API, nothing sent the marker or the prompt text anywhere, in any request body or URL.

What did go out is telemetry, update checks and two new connections. The app talks to LaunchDarkly, Amplitude, New Relic, Sentry and Postman's own event endpoint and update server, and some of that carries an installation id, the kernel version or a local log path. The installer reports to Sentry too: agent, versions, OS, outcome and a run id, which fits its header's "fixed codes and numeric version strings only". At session start both agents contacted mcp.postman.com, sending their own name and version, with no prompt and no paths, and Codex refreshed the plugin from GitHub.

All of this ran signed out, with no collections and a fake model, so no skill or MCP tool ever ran and nothing was asked to read that .env file. I did not log other ports, DNS or request headers. So the prompt did not leak in this setup, and I can say nothing about a signed-in account or a real working session. The headline's claim stays unproven, and I have not disproved it.

"installer attempts to trust its own startup hook" is in the issue's title, and whether it happens depends on which installer runs. Postman's plugin README says it outright for npx @postman/postman-plugin: "There is no separate hook prompt or dump of its instructions." I ran that command with --yes and it printed Approved Postman's Codex session-start hook. That route you start yourself.

The desktop app normally runs a bundled install.sh, and that script has no approval step, in the 12.35.1 build I tested and in the Linux package of 12.33.4, the version in the report. That is why the hook stayed untrusted in my normal runs.

The app has a fallback, though, and the fallback is the approving installer. Its code runs npx with --yes already filled in when, for example, the script is unavailable, or the plugin-auto-install-use-script flag is off or does not answer within 10 seconds. I forced that by adding one comment line to a throwaway copy of the script, so its checksum failed:

text
{"outcome":"installed","platform":"linux","exposed":true,"flagTimedOut":false,"useScript":true,"installer":"npx","scriptFallback":"checksum-mismatch"}

Still no clicks, and this time the Codex hook came up trusted. I broke the script on purpose, and the fallback needs Node 22 or newer on the machine, so this shows the path exists and says nothing about how often it runs. On that path nobody consents to the install or to the hook.

The reporter's case stays open. I can't run macOS, but I can read the Mac packages without running them. Versions 12.33.4 and 12.35.1 for Apple Silicon bundle the same install.sh, byte for byte, and in 12.33.4 the npx fallback is pinned to an older installer, 0.2.2, that has no approval code. So neither route in the reporter's version contains the approval.

Their log says "installer":"script", their config still carries a trust record, and they say themselves that it "does not prove who created that specific record." Reading the code can't tell me where it came from.

The approval itself is one config/batchWrite call to codex app-server. I sent the same call from a 10-line script. No prompt, the status went to trusted, and the instruction showed up in the next request.

A process running as you can edit your files anyway, so the review step only binds software that chooses to wait for it. I would not call that a Codex vulnerability.

Telling you afterwards ​

Postman's download page now says "The Postman app includes Postman CLI & Postman plugins, so you can use Postman from your terminal." The Wayback snapshot from 26 October does not have that sentence. I don't know when it was added or why, and a line on a download page is still no answer to a question nobody put to you in Claude Code. The issue is open, and at the time of writing no comment on it carries a Postman member badge.

This will not stay a Postman problem ​

~/.claude and ~/.codex are ordinary directories that every program you run can write to, and your agent treats what it finds there as yours. Last week the surprise was a CLAUDE.md inside a dependency. In September it was agents that never checked a plugin's pin. Now it is a desktop app.

Every developer tool wants to be in your agent's context, and a startup hook is the cheapest placement going. Expect more of them. The checks you run before installing an MCP server assume you are the one installing it.

What to check ​

These work whether or not you remember opening Postman lately:

bash
claude plugin list
codex plugin list
grep -n postman ~/.claude/settings.json ~/.codex/config.toml
ls ~/.cursor/plugins/local/postman
grep autoInstall ~/.config/Postman/logs/main*.log

On macOS the log is in ~/Library/Application Support/Postman/logs/. The Cursor line is there because the script covers Cursor too, which I did not run. In Codex, /hooks shows whether a hook is trusted.

  • Remove it. Three commands did the job: claude plugin uninstall postman@claude-plugins-official, codex plugin remove postman@postman and codex plugin marketplace remove postman. Three things stay behind, and you delete them by hand: the cached copy in ~/.claude/plugins/cache/claude-plugins-official/postman, the Postman CLI, and any hooks.state trust record in ~/.codex/config.toml. The install also added Anthropic's official marketplace to extraKnownMarketplaces in ~/.claude/settings.json, which is harmless, and that stays too. The app also has its own uninstall in the menu, which I did not try.
  • It stayed gone. After removal, relaunching the same version did not bring it back, and neither did an upgrade from 12.33.4 to 12.35.1, which logged skipped-already-triggered.
  • DO_NOT_TRACK=1 does not stop it. That turns off the installer's telemetry, and the plugins still installed with it set.
  • Put your agent config in version control. A git diff on your dotfiles catches this class of change whichever app makes it.
  • On a team, look at managed settings. With allowManagedHooksOnly the plugin still installed, but its instruction stayed out of the request, which matches the hooks reference. strictKnownMarketplaces: [] stopped the Claude Code install, and Codex still got the plugin.
  • On your own, there is disableAllHooks. It also kept the instruction out, and it turns off your own hooks along with Postman's.

I ran all of this in containers on Linux, once per scenario, on 3 and 4 November. Your platform and your flag may differ, which is why the commands are worth more than my table.

The hooks you wrote, you reviewed. The ones that arrive with an update to your API client deserve at least the 30 seconds those commands take.

(10 of 10)