I committed a file with my API keys to GitHub, which means they were publicly visible until I noticed and had to go regenerate new ones in every service I use. This is exactly the kind of nightmare scenario that novice vibers like me would love to never experience, and it turns out there’s a way to make it literally impossible.

WHAT’S AN API KEY API keys are like passwords that let your code talk to services like Stripe, OpenAI, or your database. If someone gets them, they can use your accounts and run up charges. They usually live in a file called .env that should never be shared publicly.

Claude Code has something called hooks - automated rules that run before Claude does certain things. If the rule fails, Claude gets blocked entirely. Not “Claude will try to remember” blocked, but actually blocked, every time, no exceptions.

WHERE HOOKS LIVE

  • Global (~/.claude/settings.json): All your projects, universal safety rails
  • Project (your-project/.claude/settings.json): Just this project, project-specific rules

Global hooks protect you everywhere. Project hooks handle rules that only make sense for that codebase.

GLOBAL HOOKS WORTH SETTING UP

Bash Firewall: This blocks dangerous terminal commands before Claude can run them - things like commands that delete entire folders, change security permissions in risky ways, or download and immediately run code from the internet. You won’t notice this hook until the one time it saves you from something catastrophic.

Set up a global PreToolUse hook that blocks dangerous bash commands.
Put the script in ~/.claude/hooks/ and configure it in ~/.claude/settings.json.
If something dangerous is detected, block it and explain why.

Command Logging: Logs every command Claude runs to a file. Silent, doesn’t get in your way, but useful if you ever need to figure out what happened during a session.

Create a global hook that logs every bash command Claude runs to
~/.claude/logs/commands.log with timestamps. Keep it silent.

PROTECTING YOUR API KEYS

After my API key disaster, I looked for ways to prevent it. The standard advice is to block Claude from reading secret files entirely, but that doesn’t work for vibers - we actually need Claude to use those keys to build things.

The solution that works for me is git-secrets, which lets Claude read and use your keys but blocks them from ever being committed to GitHub.

Set up git-secrets to scan for secret patterns on every commit.
I still need Claude to read my .env files, so don't block read access -
just protect the commit.

COMMIT GATE VS READ GATE Traditional security advice blocks AI from reading secrets entirely. Vibe coders need AI to use those secrets. The right approach protects the actual risk (secrets going public) without breaking your workflow.

PROJECT-SPECIFIC HOOKS

Some rules only matter for certain projects. I have an Astro site where certain pages need a specific setting or they break in production. Instead of remembering this, I set up a hook:

Create a PreToolUse hook that checks .astro files for [your specific rule].
If it's missing, block the write and explain what's wrong.

Claude gets blocked, sees the error, and fixes it automatically. I don’t have to remember the rule or catch mistakes in review.

WHAT’S WORTH YOUR TIME

  • Bash firewall (global) - Set and forget, saves you when it matters
  • Command logging (global) - Nice for “what did Claude do?” moments
  • git-secrets (global) - Essential after your first key leak
  • Project validation (project) - Worth it if your project has gotchas

DON’T HOOK EVERYTHING

It’s tempting to turn every frustration into a hook. Claude keeps forgetting your code style preference? Hook it. Claude uses the wrong folder structure? Hook it. Claude doesn’t comment code the way you like? Hook it.

I’d resist this urge. Hooks work best for things that actually break stuff or expose secrets - not for preferences. If you hook every little annoyance, you end up with Claude constantly getting blocked, error messages flying everywhere, and sessions that feel like fighting through red tape instead of building.

The stuff worth hooking:

  • Things that cause real damage (deleted files, leaked secrets)
  • Things that break production
  • Project requirements that are easy to forget but painful to debug

The stuff to leave alone:

  • Style preferences (put these in your CLAUDE.md instead)
  • “Nice to haves” that don’t actually break anything
  • Rules you’re not sure you even want long-term

If Claude keeps forgetting something and it’s merely annoying rather than destructive, a note in your CLAUDE.md or a reminder at the start of your session is probably the better move. Save hooks for the stuff that really matters.

SETTING UP YOUR OWN HOOKS

Just describe what you want to Claude:

I want to set up a hook that [describe what you want enforced].
Put it in [~/.claude/hooks/ for global, .claude/hooks/ for project].
Test that it works.

Remember, hooks turn “Claude should remember this” into “Claude cannot do this wrong.” Once you’ve had a leak or a broken deploy that could have been prevented by an automated check, you start to appreciate guardrails that don’t depend on memory - but guardrails work best when there aren’t too many of them.