Claude Code's --dangerously-skip-permissions flag hit production DB at 3am
Author 강해수 accidentally ran Claude Code with `--dangerously-skip-permissions` against a production D1 database after misconfiguring an env file, and shares the three-layer permission setup that prevented recurrence.
Score breakdown
The incident demonstrates that `--dangerously-skip-permissions` removes human oversight entirely rather than merely reducing friction, and that `.claude/settings.json` deny rules provide a harder enforcement boundary than confirmation prompts or `CLAUDE.md` instructions alone.
- 01A multi-agent loop hit 12K KV writes/minute at 3am due to a one-line counter bug, which led to the discovery of the larger issue.
- 02Claude Code had `--dangerously-skip-permissions` enabled while running D1 migrations against production instead of staging.
- 03The env misconfiguration loaded `.env.production` instead of `.dev.vars`, pointing Claude at the wrong database.
At 3am on a Tuesday, 강해수 was tracing a one-line counter bug that had caused a multi-agent loop to spike at 12K KV writes/minute and freeze. While investigating, they discovered a more serious problem: Claude Code had `--dangerously-skip-permissions` enabled and was executing D1 migrations against the production database. The cause was a misconfigured env file reference that loaded `.env.production` instead of `.dev.vars`. Because the flag was set, Claude never surfaced a confirmation prompt. The migration happened to be `ADD COLUMN` rather than `DROP COLUMN`, so no data was lost — but the author describes it as "survivable. But only barely."
Over two weeks after the fix, Claude attempted zero production DB commands; three deny events were logged, all traced to ambiguous prompts the author wrote during fast context-switches.
The core insight from the incident is a reframing of what `--dangerously-skip-permissions` actually does: it isn't "skip the annoying confirmation popups" but rather "remove the only moment a human sees what command is about to run." Simply turning the flag off was deemed insufficient, since a tired developer at 3am will click through prompts anyway. The more durable fix was a deny rule in `.claude/settings.json` using `"deny": ["Bash(wrangler d1 execute *)"]` paired with a more specific `"allow": ["Bash(wrangler d1 execute * --local*)"]`, so local calls pass through while all other executions are blocked before they run. Over two weeks after the fix, Claude attempted zero production DB commands; three deny events were logged, all traced to ambiguous prompts the author wrote during fast context-switches.
The full three-layer defense combines the `settings.json` allowlist, a dedicated git worktree for migration work that physically contains only staging credentials, and a `CLAUDE.md` file instructing Claude to ask before touching production. The author notes a real limitation of the `CLAUDE.md` approach: in long sessions, those instructions lose weight as context grows, so anything critical needs to be restated directly in the prompt itself. The post also flags that MCP tool permissions behave inconsistently with the deny rules, with full details on the worktree setup and `CLAUDE.md` wording available at riversealab.com.
Key facts
- 01A multi-agent loop hit 12K KV writes/minute at 3am due to a one-line counter bug, which led to the discovery of the larger issue.
- 02Claude Code had `--dangerously-skip-permissions` enabled while running D1 migrations against production instead of staging.
- 03The env misconfiguration loaded `.env.production` instead of `.dev.vars`, pointing Claude at the wrong database.
- 04The migration was `ADD COLUMN`, not `DROP COLUMN`, so no data was lost.
- 05A `.claude/settings.json` deny rule blocks all `wrangler d1 execute` calls except those with `--local`, stopping production DB commands before execution.
- 06Over two weeks post-fix, Claude attempted zero production DB commands; three deny events were logged, all from ambiguous user prompts.
- 07`CLAUDE.md` instructions lose weight in long sessions as context grows, so critical constraints must be restated in the prompt itself.
Topics
Summary and scoring are generated automatically from the original article. We always link back to the publisher and never republish images or paywalled content. Last processed Jun 19, 2026 · 10:25 UTC. How this works →