Did My Coding Agent Send My API Key?

2026-11-06

I had a Stripe key in a file named .env and a coding agent that I had already allowed to run curl. A coding agent is the program that opens your files and runs commands, not the chat box you type into. An API key is the long password a website checks before it will do the work. The question was simple and late: did my coding agent send my api key. Stroq can answer that from the session files already on the disk. A session is the saved record of what the agent read and which commands it ran. On a built-in sample it named one made-up key as sent. On a replay of 36 bad sessions it blocked 15, asked about 21, and let 0 through. A scan does not stop the next command. The guard does, and only after you install it.

Commands and the sample numbers checked against Stroq on GitHub and stroq.dev in November 2026.

Stroq reads key files and saved agent sessions, then names a key and decides block, ask, or allow

What is Stroq?

Mind map of Stroq: scan sessions, name keys, block or ask, install the guard, limits vs a sandbox

Stroq is a local program that reads your own agent sessions and, if you install it, stands in front of the next command. It does not phone home, and the report prints the name of a key, never the value.

Think of two jobs that people mix up. The look-back job reads history. Claude Code, Codex, and Cursor already write that history onto your computer when you use them. Stroq compares those transcripts with keys it finds in your own files, such as .env, the AWS credentials file, .npmrc, .netrc, and the Docker config. It keeps a fingerprint of each secret, a short code that can be matched later and cannot be turned back into the password. The look-forward job is a hook. A hook is a check the agent runs before a command is allowed to start. It is not a reminder in the chat. If the check says no, the command does not start.

I expected a lock on the whole computer. What Stroq actually is, is a filter on the text of the action. A command that hides the key inside a script, a file, or a variable can still carry it out, because Stroq never sees the value. That limit is the one to remember before you trust a green report.

Did my coding agent send my API key?

Yes, you can check, and the check I ran did not read a real key. npx @stroq/cli sent --try uses a made-up session. It reported one key out of one, marked sent to another company. The name was STRIPE_SECRET_KEY, the file was .env, and the command was curl to collector.example. It told me to revoke that key and update the file. It did not print the secret.

That is the shape of a real finding too. Stroq calls a send only when the key’s value sits in the command that left the machine. A line that only says the key was visible to the agent is a different bucket: seen, used with its own service, maybe sent, or blocked before it ran. The sample also said a key written into a call was written by the AI, so the company that runs the model saw that text as well. Seeing is not the same as a curl to a stranger.

On your own machine the same command without --try is npx @stroq/cli sent. It needs Node 22 or newer. Node is the program that runs JavaScript tools on your computer. The command reads the last stretch of Claude Code, Codex, and Cursor sessions, prints names, and writes nothing but a small cache under your home folder. If you have never used those tools, the report will be empty, and empty means “no sessions,” not “you are safe.”

How does Stroq decide to block a command?

It blocks when the command is trying to leave the machine with a known secret, or when it is trying to run code it fetched or decoded. It only asks when the danger is real but the text is not a known secret leaving the machine.

Stroq decides to block a command that leaves with a known key, ask when text was copied or destructive, or allow

I ran npx @stroq/cli attack on the copy tagged 0.30.0. It replays 36 recorded bad sessions in a throwaway home, so it does not read your real keys. The result was 15 blocked and 21 asked. Zero were allowed. The command exited clean, which is what it does when nothing slips through.

The blocks I care about were concrete. A readme that told the agent to pipe a download into the shell was denied. Posting a .env token into a GitHub comment was denied. A web fetch whose address carried a repository token was denied. A downloaded skill that hid an installer inside encoded text, then piped it into a shell, was denied. A guide that told the agent to delete its own hooks was denied. An instruction file that hid the same request in invisible characters was denied too.

The asks are the turn. Deleting a directory in your home was not denied. It was a question, under a rule for destructive commands. Force-pushing a database change that drops tables was a question. Piping the environment to an outside host, after a poisoned note, was a question, because the command had been copied from text the agent had just read. Copied means Stroq saw the same snippet in an earlier file, page, or tool result. Tool output is data. It is not an order from you. Stroq will say so, and then it will wait.

If you approve every question without reading it, those 21 still run. The filter did its job. The habit undoes it.

What the replay didHow many of 36What that means for you
Blocked15The command does not start
Asked21The command starts if you say yes
Allowed0Nothing in this set got a free pass

How do I check a session without installing a guard?

Run the sample first, then the replay, and do not install anything until both look like the numbers above.

You need Node 22 or newer. From any folder:

npx @stroq/cli sent --try
npx @stroq/cli attack

sent --try should name one made-up key and a curl, and it should say it read nothing on your machine. attack should finish with none allowed. If a future copy lets one through, the command exits with an error on purpose. That is the check you can repeat in a few minutes.

Only then, if you want the look-back on your real sessions:

npx @stroq/cli sent

Read the names. Rotate any key it marks as sent to another company. Rotating means you revoke the old password at the website that issued it, write a new one into .env, and treat the old one as public. Do that even if you feel sure the transcript was “just a test.” The value was in the command text.

A scan still does not change the next session. People stop here and feel finished. They are not.

How do I stop my coding agent from sending secrets?

Install the guard, then answer the questions it asks. The scan you already ran will not do this part.

npx @stroq/cli init
npx @stroq/cli doctor

init with no extra flag is aimed at Claude Code. It registers the before-command check. doctor tells you whether that check is actually installed. For the other tools the same installer takes a name:

npx @stroq/cli init --agent cursor
npx @stroq/cli init --agent codex
npx @stroq/cli init --agent copilot
npx @stroq/cli init --agent windsurf

There is also a Claude Code plugin path, stroq from the AGGIB/Stroq marketplace, which wires the same checks without editing your settings file by hand. If the program that runs the check cannot even start, the before-command step fails closed: the command is blocked rather than quietly allowed. That is the right failure. A guard that disappears when the network is slow is not a guard.

Do not install this, or anything else, by piping a downloaded script into a shell. That is the pattern the first replay case exists to stop. npx downloads the package and runs it. You can read the project at github.com/AGGIB/Stroq before you do.

After it is in, the next dangerous command should stop or ask. A normal edit of a source file should not. If every keystroke becomes a prompt, the rules are too loud and you will start clicking yes. That is worse than not installing it.

Stroq vs the permission prompt you already click

The permission prompt asks you to trust a command before you have seen whether it contains a key. Stroq looks at the value.

Claude Code already asks before many shell commands. That prompt is a person clicking yes. It does not know which strings in the command are passwords, and it does not remember that the command was copied from a web page the agent opened a moment ago. Stroq’s look-back does the first job without any install. Stroq’s guard does the second job, and it can deny instead of asking when the text contains a known secret and the command is leaving the machine.

Permission promptStroq scanStroq guard
When it runsBefore a command, if the product asksAny time, on sessions you already haveBefore the next command, after init
Knows your .env valuesNoYes, and prints the name onlyYes, and can deny a send
Stops a download piped into a shellOnly if you click noNoYes, on the replay
Stops “delete my home folder”Only if you click noNoNo. It asks
Locks the whole computerNoNoNo

Use the prompt as the habit you already have. Add the scan when you want to know about a session that already ran. Add the guard when you want a no that does not depend on you spotting a key in a long command. Skip the guard if you will not read the questions. Twenty-one of the thirty-six cases were questions.

This is a different job from reviewing the code for bugs. A full pass over the repository, with a second pass that tries to prove each bug wrong, is the security audit skill. Stroq will not find a missing check in your login code. That audit will not tell you that an earlier curl contained STRIPE_SECRET_KEY.

When is Stroq not enough?

Stroq is not enough when the agent can run a program you cannot see, or when the secret never appears as text.

Use a locked room, not a filter, when the agent installs packages, runs tests, and you do not want it to touch the rest of the computer even if the filter misses. A filter reads the command. A locked room stops the program from reaching files and the network except where you opened a door. Those are different products. The cage around a coding agent is that second job.

Use a version list, not Stroq, when the fear is “did I install a bad package.” Stroq does not compare package versions. A read-only scanner that matches names and versions against a known-bad list is the right tool there, and the steps live in how to check for a malicious npm package.

Use a shorter rules file, not Stroq, when the agent is merely writing extra files you did not ask for. That is a behavior problem, and the brake is how to stop Claude Code from overengineering. Stroq will not care that the agent invented a new framework. It cares that the agent is about to send a key or delete a hook.

Three misses to keep next to the install:

  • A key Stroq has never seen, because it is not in those credential files, will not be named.
  • A key that leaves inside a script, where the command line does not contain the value, will not be called a send.
  • A match in a transcript does not, by itself, prove a model company stored the key. It proves the text was in the session. The sample’s curl case is stronger than that, because the value was in the command that left.

I would still run sent after any session where the agent touched .env. The cost is one command. The miss is quieter than the hit.

Is Stroq worth it?

It is worth it if you already let an agent run commands and you will read the questions. It is not worth it as a substitute for a locked room, or as a promise that every secret on the machine is covered.

The part I would not skip is the ten-minute check, even if you never install the guard. sent --try shows you the shape of a real report. attack shows you that “protected” includes a lot of questions, including the one about deleting your home directory. If that trade feels wrong, do not install it and then click yes. Decide first.

If the trade feels right, init and doctor, rotate anything sent marks as sent, and leave the guard on for the next session. The project and the docs are at github.com/AGGIB/Stroq and stroq.dev.

Common questions about Stroq and API keys

Does Stroq print my API key?

No. The report prints the key’s name, the file it came from, and the kind of command. The value stays off the screen. The sample I ran named STRIPE_SECRET_KEY and never showed the secret.

Does a scan stop the next command?

No. sent and sent --try only report. The next command is unchanged until init installs the guard and doctor says the check is present.

Does Stroq work with Cursor and Codex?

Yes. The scan reads Claude Code, Codex, and Cursor sessions. The guard installs with init --agent cursor or init --agent codex, and the same flag covers Copilot CLI and Windsurf. What each host lets the check see is not identical, so a deny you watched in Claude Code can be an ask, or a miss, in another host. Run attack once on the host you actually use before you trust the habit.

Is Stroq a sandbox?

No. A sandbox is a locked room around the program. Stroq is a filter on actions the agent admits it is taking. A command that hides the secret, or a program the filter does not wrap, is outside that promise. If you need the room, use a room. If you need to know whether an earlier curl carried the key, use Stroq.

Leave a comment