DEV Community

intothewild
intothewild

Posted on Edited on

I Built a Local Secret Scanner That Intercepts AI Coding Agents Before They Write to Disk

AI coding agents are incredibly fast, remarkably helpful, and completely unaware of which strings are secrets.
Existing scanners like Gitleaks and TruffleHog are excellent tools, but they primarily catch secrets after they have already been written to disk—whether that is locally at commit time or downstream in your CI pipeline.

Once an autonomous agent is in your loop, that window is too wide. Tools like Claude Code and Cursor will happily paste a live API key directly into a file or an unmasked curl command if they aren't stopped. I wanted a way to check content before the write operation even happens.
So I built StagedSec.

What it does

StagedSec uses a single detection engine that intercepts secret leaks at three critical development points:

Where How it works

Terminal
stagedsec scan runs as a pre-commit hook checking exactly what is staged.

Editor
A native VS Code extension highlights secrets as you type and provides rotation guides.

AI Agent
A Claude Code hook and a Model Context Protocol (MCP) server inspect content right inside the agent's write loop.

Core Design Philosophy

• 100% Local Execution: Everything runs directly on your machine.
• Zero Overhead: No accounts to create, no tracking, and no external telemetry.
• The Single Network Exception: There is a completely opt-in --verify-aws flag. When enabled, it reaches out to check if an identified AWS key is actually live. It is entirely turned off by default.

Current State & Honest Limitations (Roast Me)

This is currently at version v0.1.
To be completely transparent about where it stands:
• It has about 70 detection rules compared to Gitleaks’ ~220.
• On a fresh, untuned set of token types, its current hit rate is roughly 50%.
• The complete benchmark harness—including the exact test cases where the scanner currently loses—is included directly in the repository. I'd much rather you see where it fails directly from me.
The project is written in Go and is entirely MIT licensed.
I would love to get the community's feedback on this. Specifically, opening issues regarding false positives or missed secrets in your own agent workflows is the most helpful thing you can give me right now to improve the ruleset.
Main Repository: https://gitlab.com/stagedsec/stagedsec
github repo: https://github.com/stagedsec/stagedsec

Top comments (10)

Collapse
 
aisovereign profile image
Ananya Soni •

Hey, I'm the founder and CEO of AGI Systems Directorate. We mostly work on brain-replicated models, autonomous agents, and robotics.

Catching leaked secrets before an autonomous coding agent writes them straight to disk is a massive pain point everyone deals with, so intercepting the write loop right at the MCP and hook level is a super clean solution. We run into similar headaches with our own agent execution pipelines, so I'm definitely pulling this repo and testing it out. Being a founder building this stuff means you're constantly fighting these exact micro-architectural fires.

Curious about one technical detail: how are you handling streaming chunks where the agent drops partial payloads before the full write call hits the hook? But seriously, being a founder and CEO is not so easy.

Collapse
 
intothewild9 profile image
intothewild •

Thanks for checking it out! The hook runs only after the agent finishes a tool call and it gets the full content so partial chunks never reach the disk. If you try it, I’d love to hear what it catches or misses in your setup.

Collapse
 
aisovereign profile image
Ananya Soni •

Makes total sense—waiting for the tool call completion payload definitely saves you from dealing with broken token chunks mid-stream. Tested it across a mix of API keys, auth tokens, and passwords in our pipelines and it caught everything cleanly.

Quick technical Q: are you running purely pattern and entropy-based matching on the final payload, or do you have any AST-aware filtering built in to cut down on false positives when agents spit out dense mock configs or test fixtures?

Also, we mostly live in the trenches building AGI architectures, autonomous agents, and robotics. Honestly as a founder and CEO I don't even use AI coding agents for all my work—just sometimes—but I've totally seen that exact security panic where agents accidentally leak live keys publicly. Having a proper interceptor for this is a lifesaver because agents love doing that. What's your main focus day-to-day?

Collapse
 
analista_83 profile image
Sammi De Blas •

Intercepting at the write boundary is the part most scanners skip. Reporting a secret after it lands in a commit leaves it in history forever. The interesting question is how the hook behaves when an agent retries the same file several times in one run, because a pre-write check that blocks every retry just pushes the agent to write the secret somewhere else.

Collapse
 
intothewild9 profile image
intothewild • • Edited

Thanks Sammi and thanks for the follow! Great question. Right now every tool call is checked on its own so like if the agent tries the same secret in another file or in a shell command that gets blocked too. But I don’t track repeated retries across a session yet. That’s a good idea, so I’ll add it as an issue. The main gap is that obfuscated secrets (split or encoded) can slip past regex detection which I list in the README limitations.
here is the issue : gitlab.com/stagedsec/stagedsec/-/w...

Collapse
 
intothewild9 profile image
intothewild •

Update: a first version is in. It counts blocks per session (only a count, timestamps and rule IDs, never secrets), and from the 3rd block the deny message gets firmer (--escalate-after N). It’s advisory, not a lock-out. One thing I haven’t verified yet is whether Claude Code and Cursor send a stable session id in practice. Details are in the issue: gitlab.com/stagedsec/stagedsec/-/w....
Thanks for the idea!

Collapse
 
analista_83 profile image
Sammi De Blas •

Cross call checks could stay in memory and be opt in. That keeps the state file clean and still catches split secrets.

Collapse
 
analista_83 profile image
Sammi De Blas •

Encoding is the easy miss. Normalising base64 and joined string literals before matching catches most of it.

Collapse
 
analista_83 profile image
Sammi De Blas •

Tracking retries across a session is where obfuscated secrets show up. The same secret split over two calls looks odd.

Collapse
 
intothewild9 profile image
intothewild •

Good point, and that’s a real gap. Each call is scanned on its own, so a secret split across two calls wouldn’t match in either one. Catching that would mean remembering fragments between calls, which conflicts with a rule I set: the state file never holds anything derived from a secret. So the likely first step is splitting within one call (adjacent string literals, base64) .tracked in issue #2. Cross-call detection would need an opt-in, in-memory-only approach. Thanks for pushing on it