// docs / security guides / claude code checklist
Чек-лист безопасности Claude Code: 26 пунктов
Claude Code (Anthropic's CLI agent) generates entire codebases via slash commands, manages multi-file refactoring, and reads/writes files through bash. This checklist targets Claude Code's specific risks: no default security policies, rate-limiting rarely added, <code>.claude/CLAUDE.md</code> as your security-guardrail file, and the risk of committing <code>.env</code> or cached tokens. 26 items across secrets, database, auth, headers, deployment, and Claude Code-specific gotchas.
PRE = pre-deploy (audit your source). DEPLOY = at deploy time. POST = post-deploy verification. Items reference FixVibe check IDs in category.check-id form where relevant.
Secrets and API keys (5 items)
Claude Code reads entire source trees and outputs whole files. Secrets in your context become secrets in the output.
- PRE — Create
.claude/CLAUDE.mdwith security policies. Add: "Security Rules: Never inline service_role keys into client bundles. Always route sensitive operations through server-only endpoints. Verify that NEXT_PUBLIC_* env vars contain only safe values (no keys, no tokens)." Claude Code reads.claude/CLAUDE.mdfor project guidance. - PRE — Ensure
.env.localis in.gitignore. Claude Code may accidentally commit.env.localduring a refactor. Rungit ls-files .env*to check what's tracked. If.env.localis present, it's exposed. - PRE — Audit generated API routes for env-var verification. Claude Code sometimes forgets to verify that
process.env.SECRETexists server-side before using it. Routes should fail fast if an env var is missing, not fall through to a default. - PRE — Check the
.claudecache directory. Claude Code caches conversation context in.claude/cacheor.claude/history. These files should not be committed. Add.claude/to.gitignore. - POST — Run secrets.browser-storage on the deployed app. If Claude Code inlined a key, the passive scan will find it in the rendered bundle.
Database access control (4 items)
Claude Code is excellent at generating schema, but RLS policies need explicit instruction.
- PRE — Instruct Claude Code on RLS in
.claude/CLAUDE.md. Add: "Every migration must includeALTER TABLE ... ENABLE ROW LEVEL SECURITYandFORCE ROW LEVEL SECURITY. Every policy must validate the user'sauth.uid()." - PRE — Review generated migrations for
FORCE ROW LEVEL SECURITY. Claude Code may generateENABLEbut forgetFORCE. WithoutFORCE, table owners (the migration runner) bypass RLS. Manually add it if missing. - DEPLOY — Test RLS enforcement after deploy. Open Supabase Studio, pick a table, confirm RLS toggle is ON. If Claude Code's migration used
ENABLEwithoutFORCE, the toggle will say ON but enforcement is incomplete. - POST — Run the baas.supabase-rls active check. It attempts a write with the anon key. If it succeeds, RLS is incomplete. Add
FORCEto the migration and redeploy.
Authentication and sessions (4 items)
Claude Code generates auth flows well but doesn't automatically add rate-limiting or verify all token claims server-side.
- PRE — Mandate server-only auth verification in
.claude/CLAUDE.md. Add: "Every API route that mutates data must verify the user withawait supabase.auth.getUser()on the server. Never trustgetSession()or user ID from the request body." - PRE — Check generated auth handlers for token expiry. Magic-link and password-reset tokens need server-enforced
expires_at. Ask Claude Code: "Add a check that rejects tokens older than 1 hour." - PRE — Verify sign-in redirect guards. The
nextparam redirect must start with/and not//. Add to.claude/CLAUDE.md: "Validate thenextparameter: must start with/, reject if it starts with//or contains a protocol." - POST — Test logout clears cookies. Sign in, sign out, inspect Application → Cookies. The session cookie must be cleared. If it persists, the logout endpoint isn't destroying state.
HTTP headers and CSP (3 items)
Claude Code doesn't generate middleware by default unless you ask.
- PRE — Add middleware request to
.claude/CLAUDE.md. Include: "Generatesrc/middleware.tswith Content-Security-Policy using a per-request nonce, HSTS, X-Frame-Options, and X-Content-Type-Options headers." Then ask Claude Code to implement it. - PRE — Verify
src/middleware.tsexists and has CSP. With Next.jssrc/layout, middleware must be atsrc/middleware.ts, not the project root. Verify the CSP header includes'strict-dynamic'and a nonce. - POST — Run headers.security-headers on the deployed URL. The check reports missing headers and suggests fixes for your platform.
Deployment hygiene (4 items)
Claude Code doesn't configure your deployment platform — that's your responsibility, but worth checking.
- DEPLOY — Scope env vars per environment in Vercel (or equivalent). Settings → Environment Variables → assign each secret only to Production. Never share
sk_live_*with Preview or Development. - DEPLOY — Audit your CI workflow for secret echo. If GitHub Actions or another CI has
echo $SECRETanywhere, remove it. Build logs are archived; secrets in logs are compromised. - DEPLOY — Prefer platform-native secret storage. Vercel's Settings → Environment Variables is encrypted; GitHub Actions secrets are better than nothing but don't match platform-native storage.
- POST — Rotate any key that reached a public build. If a key appeared in a Vercel Preview URL or any public artifact for even seconds, it's compromised. Rotate immediately.
Claude Code-specific gotchas (5 items)
Patterns unique to Claude Code's architecture and workflows:
- Claude Code forks work into subagents. On large tasks, Claude Code may spawn multiple subagent instances, each with partial codebase context. If one subagent hallucinates a secret-safe pattern that another doesn't, inconsistency emerges. Review the final diff carefully.
- Bash operations are unverified. Claude Code executes bash commands directly.
git commit -m "fix"is convenient, but if the working directory has a.envfile and a glob includes it, it commits. Always reviewgit diff --cachedbefore Claude Code commits. - Context window boundaries create gaps. If your codebase is large, Claude Code's context may split across multiple windows. One window's
.env.localhandling might differ from another's. Enforce the policy in.claude/CLAUDE.mdand verify the output. - Rate-limiting is almost never added without asking. Claude Code generates working CRUD but rarely includes rate-limiting headers or exponential backoff logic. Explicitly ask for it in
.claude/CLAUDE.md. .claude/CLAUDE.mdis read but not enforced. Claude Code reads your.claude/CLAUDE.mdas a hint, not a constraint. If the hint conflicts with the task, Claude Code may ignore it. Always review the output.
Next steps
Check the general vibe coding security checklist for 44 cross-tool items, then see step-by-step hardening for deploy-time patterns. If you're also using Cursor, see the Cursor security checklist.
