Skip to content
karolkozerPublic

About

Why your AI agent reached for your secrets - from Claude Code and Codex transcripts

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

agentwhy

npm version License: Apache 2.0

Your AI agent reads your files. Find out which ones, and why.

agentwhy reads the conversations Claude Code, Codex and GitHub Copilot already save on your computer and shows which of your private files (.env, keys, secrets) an agent opened, the task that led to it, and which key to change.

Try it in your browser first, on a made-up project: the demo.

A report on a demo project: a helper read the keys in a .env file, repeated them and passed them back to your AI, shown as a story and then as a diagram

Why you need this

You ask Claude Code something ordinary: "Find out why our Stripe webhook started failing." It starts a helper agent, and the helper goes looking for the webhook secret. Three things make this hard to notice:

  • Your rules don't reach the helper. Your AGENTS.md says "never read .env files". The helper only gets its task, not your rules, and the task says to find the secret.
  • A search names no file. grep -rn STRIPE . prints the key without ever opening .env by name, so no rule that blocks .env can stop it.
  • Nothing tells you. There is no prompt, no warning, no log you would look at. The key is now in the chat, in the saved conversation on your disk, and with the model provider. Deleting the log does not bring it back. Only changing the key does.

agentwhy reads that saved conversation afterwards and shows you all three: the task, the search, and the key to change.

Run it

npx @agentwhy/cli

Run it in your project folder. It reads your saved conversations from the last 7 days, on your computer, by fixed rules, and opens a page in your browser with a short list: which private files were reached, by whom, and what to change. Most days it says there is nothing to do.

Needs Node 22 or later. Made and tested on a Mac. On Windows, agentwhy is new and still being tested. Something not working? Tell me on GitHub.

Nothing leaves your computer

  • No internet. agentwhy reads the conversations already saved on your disk. The only connection it opens is a small server on 127.0.0.1, for the page in your browser. --no-serve skips even that.
  • No AI model, no account. agentwhy calls no model: every finding comes from fixed rules. What it tells your AI, in the chat, is a file's name, never what is in it. There is nothing to sign up for.
  • No secret in the report. Values are replaced before the report is built. The page names the file and the key to change, never what is in it.

The one download is npm's: npx fetches the package the first time it runs it, as it does for any package. Check the rest yourself: turn off Wi-Fi and run it, or list its connections with lsof -nP -iTCP -a -c node while it runs. More in Can you trust it?


What you see

The pictures below are of a demo project.

Conversations. Every time your AI worked for you this week, and which of those times it read something private.

The Conversations page: nine conversations this week, three of them marked as needing attention

Open one and you get a to-do list: the private file your AI read, and a Fix it button that walks you through making it safe. For a file you want kept private, the page asks what should happen next time: Block it - your AI can't open it or search through it - or Track it - your AI can still read it, and you get a message every time it does.

What happened. The story of one file, step by step: who read it, where it was repeated, and where it ended up.

What happened to this file, as a story: a helper read the keys, repeated them in a message and passed them back

The same story as a diagram, from your request to the file:

What happened to this file, as a diagram: you, your AI, a helper, the .env file, and the point where it was exposed

The to-do list, the full record, the files your AI opened and the helpers it brought in: the pages, in pictures.

In the terminal, the same kind of finding looks like this:

  the session itself · 4 actions · 1 file reached · wrote the value into files
  └─ Agent 1 · Explore · 2 actions · 1 file reached · 1 refused · gave the value back

  Agent 1 · Explore, asked to "Find why the webhook returns 500"
    ● apps/web/.env.development  in a result  reached
    ○ apps/web/.env.local        named        refused
    ↩ its answer to the session itself carried a value from apps/web/.env.development

Read it top to bottom:

  1. Your agent started a helper (Agent 1) and gave it a task: find why the webhook fails.
  2. It tried to open .env.local. A rule stopped it (○ refused).
  3. A search got through anyway. It printed lines from .env.development, and the secret came along (● reached, in a result). No command named that file, so no rule applied.
  4. The helper handed the secret back to your main agent (↩), which wrote it into a file.

What to do: change that key at the service that issued it. agentwhy tells you which one. It never shows the value itself.

If agentwhy found something on your machine, a star helps the next person find it.

What agentwhy shows you

The cause, not only the file. Other tools can say "a file was read". agentwhy shows the task that led there: which agent asked which helper to do what, and where the value went next.

Conversations from before you installed it. It reads the records Claude Code, Codex and Copilot already keep, weeks back. There is nothing to set up first.

The routes no rule catches. Secrets that came in through a search result, and reads a rule refused. Claude Code records neither as an event you would see.

Protect it from now on

Both steps are optional.

  1. This project. npx @agentwhy/cli init adds rules to Claude Code that refuse the obvious reads - and to Codex, in a project that uses it - and a one-line notice in the chat when a secret gets into the conversation. It shows exactly what it will write and asks first.
  2. What belongs to no project. Your SSH keys or a cloud login are in no project folder. npx @agentwhy/cli protect "~/.ssh/**" - or the page, run from your home folder - keeps that place from your AI wherever it works: Claude Code's own file tools, and the shell commands agentwhy checks. The rule names the place, not just a name. Measured on a Mac, in Claude Code's terminal; VS Code, the desktop apps and Windows are not measured yet.

By default it treats these as private: .env*, *.env, .npmrc, secrets/, .ssh/, id_rsa*. Add your own with init --protect "config/*.pem".

A key can sit in a file you never listed. If you want, one switch in Settings, or init --hide-keys, swaps a key agentwhy recognises for a placeholder before Claude Code's AI reads it, and tells the AI so. The welcome page turns it on for a project it sets up, and Settings turns it off; with npx, each step of your AI then takes about half a second longer. It does not cover a command that fails, a file you attach to a message, part of a key, a key that is encoded or split, or a password of no known format, so it lowers the risk and does not remove it. Measured on a Mac: by script in Claude Code's terminal, by hand in VS Code and the Claude desktop app.

Where you use Codex, the same switch adds a hook to your own ~/.codex and approves it, and Codex then hides a key in what a shell command printed, in the projects where the switch is on - after a command that fails too. Codex's AI reads such a result as an error, and the key stays in Codex's own record of the command - Codex's terminal shows you the last lines of a command that failed, key included. Turned off in one project, the hook stays for the others; init --remove --hide-keys --codex takes it out. Measured on a Mac: by script with codex exec 0.166.0, by hand in Codex's terminal, its desktop app and VS Code.

In Claude Code, as a plugin

agentwhy is also a Claude Code plugin, so you don't have to remember the command:

  • In a terminal, in Claude Code 2.1.275 or later: /plugin install agentwhy --marketplace karolkozer/agentwhy, then Install for you.
  • In the Claude desktop app, from the Code tab: Customize > Plugins > Add > Add marketplace > Add from a repository, type karolkozer/agentwhy and Sync, then Add agentwhy under Discover.

Then type /agentwhy:report in a Claude Code conversation (in the desktop app, the Code tab). The first time it opens the setup; after that, this conversation's report. agentwhy does not work in the desktop app's Chat tab, which runs no plugin's hooks.

Install for you, and the desktop app's Add, mean every project on this computer. From your next conversation, agentwhy tells you in the chat when your AI reads a private file, in any project. It blocks nothing you have not chosen to block on its page. Turn it off or remove it where you added it: the Plugins window in the desktop app's Code tab, or /plugin in a terminal.

Can you trust it?

A tool that reads your conversations and knows where your keys are should not be taken on faith. Each claim below can be checked without reading the source.

Claim How to check it
Nothing goes over the internet. The only socket it opens is a small server on 127.0.0.1, so the page can save what you mark as done. --no-serve skips even that. Turn off Wi-Fi and run it: it behaves the same. Or, while it runs, lsof -nP -iTCP -a -c node lists only a 127.0.0.1 listener.
Your secrets never reach the report. Values are replaced before the report is built, and the code's types forbid a raw value there. Open a report and search it for a key you know is in your .env.
No AI model is called. Every finding comes from reading the records, by rules. Run it offline with no API key set: the result is the same.
One dependency, pinned. Only @clack/prompts, for the questions init asks. 6 small packages in total. npm ls --omit=dev --all in the installed package.
The package is what this repository built. Every release after the first is published from a tagged commit by GitHub Actions, with npm provenance. The first is published by hand, because npm lets a trusted publisher be set up only for a package that already exists. The Provenance badge on npmjs.com, or npm audit signatures.

Questions

Does it stop my agent from reading secrets? It stops the obvious routes. init adds rules for Claude Code's own file tools, and a check that refuses a shell command that would read a private file: cat .env, grep -r over a folder that holds one, a glob such as cat .env*. The same check runs in Codex from the first message, and in GitHub Copilot once you turn it on. It is not a sandbox: a path built while the command runs, a script, or a command handed to another shell (sh -c '…') can still get through, and that is why the main job is telling you what actually happened. Details for each AI.

Which agents does it work with? Claude Code in the terminal, in code editors and in the Claude desktop app. Codex in the terminal, in VS Code's panel and in the ChatGPT/Codex desktop app. GitHub Copilot's CLI, its desktop app and VS Code's agent mode. Not Cursor's own AI, Windsurf or chats on claude.ai. Codex and Copilot write down less than Claude Code does, so their reports answer fewer questions: what each AI's report tells you.

What if it finds something? It names the file and the key to change, worst first. Changing the key at the service that issued it is the only step that undoes a leak. Mark it done and it leaves your list.

Does it look at all my projects? One project at a time: the folder you run it in. The page lists your other projects so you can switch.

What does it cost? Nothing. agentwhy is open source under the Apache License 2.0, commercial use included. See License.

How well it works

Measured on 29 scripted sessions, each one a route by which a secret can reach an agent, including the routes it misses (docs/detection.md, re-run with npm run measure:detection):

  • when a private file's value came into the conversation, it said to change the key in 14 of 18;
  • it named the task a helper agent was given in 5 of 5;
  • no part of a secret reached a report in 29 of 29.

The misses are listed there, with why: an interpreter that builds the file's path while it runs, a library that opens the file, a glob, an MCP tool, a pasted key. These are routes written by the author, not a rate on real machines. How often each happens in real work is not measured yet.

Status. Released on npm since 30 September 2026 and updated often. The reader, the report and the link between a main conversation and its helpers are built and tested, for Claude Code, Codex and GitHub Copilot. The 29 sessions above are Claude Code's. If agentwhy reads one of your conversations wrongly, say so: that is how the routes above grow.

Usage

npx @agentwhy/cli                  # every conversation in one page, start here
npx @agentwhy/cli check            # the short answer, in the terminal
npx @agentwhy/cli report --open    # the newest conversation, in the browser
npx @agentwhy/cli init             # protect this project and add the chat notice
npx @agentwhy/cli protect <path>   # keep a file from your AI in every project on this computer
npx @agentwhy/cli notify           # what you are told when a turn ends, and where

Every command, flag and hook, and what each word on the page means: docs/reference.md.

Author

agentwhy is made by Karol Kozer (LinkedIn, @KozerKarol on X). Before it, Karol made Planby, which won first place at WaysAwards 2024, hosted by WaysConf, and has over 1,700 stars on GitHub.

Something else in mind? Write to karol@agentwhy.dev. Every message is read, and most get an answer within a day or two.

License

Copyright 2026 Nessprim Karol Kozer.

Open source, under the Apache License 2.0. Use it, change it and share it for any purpose, commercial use included. When you pass on a copy, keep the license, the copyright and NOTICE with it. The license does not cover the name agentwhy. The full terms are in LICENSE; this summary does not replace them.

More

docs/reference.md: every command and flag, the full report, each AI's details, and the limits of what it can tell you · CONTRIBUTING.md: how to work on it · THIRD_PARTY_NOTICES.md: bundled third-party code · © 2026 Nessprim Karol Kozer.

About

Why your AI agent reached for your secrets - from Claude Code and Codex transcripts

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages