Free Download
Make AI coding tools refuse to leak your secrets
One config file tells Cursor, Claude Code, Copilot, and Windsurf to never hardcode API keys. Drop it in your project root. Done.
Cursor Security Rules
# Security Rules for Cursor AI # Drop this file in your project root. Cursor reads it automatically. # Source: devsafe.com/ai-safety-templates # === Secret Protection === # NEVER hardcode API keys, tokens, passwords, or secrets in source files. # ALWAYS use environment variables: process.env.X, os.Getenv(), os.environ.get() # NEVER put secret keys in client-side or frontend code. # NEVER read .env files into AI context or paste their contents. # NEVER commit .env files to git. Only .env.example (with empty values). # === Config Generation === # ALWAYS reference .env.example for the correct variable names. # ALWAYS use ${VAR} references in docker-compose, MCP configs, and CI files. # NEVER generate connection strings with literal credentials. # === Escape Hatch Prevention === # When asked to "make it work quickly" — still use env vars. No shortcuts. # When a test needs credentials — use clearly fake values (test_xxx, example_xxx). # When generating setup scripts — use variable references, never literal values. # === MCP Security === # NEVER put API keys inline in MCP config JSON files. # ALWAYS use environment variable references in MCP server configs.
Save as .cursorrules in your project root (same level as package.json or go.mod). Cursor reads it automatically at session start.
Claude Code Security Rules
Security rules for this project: - NEVER hardcode API keys, tokens, passwords, or secrets in any file - ALWAYS use environment variables (os.Getenv, process.env, Deno.env.get) - NEVER put secret keys in client-side or frontend code - NEVER read .env files into context or display their contents - NEVER commit .env files — only .env.example (with empty values) - ALWAYS check .env.example for the correct variable names before generating config - When generating docker-compose, MCP configs, or setup scripts: use ${VAR} references, not literal values - When the user says "make it work" or "connect it fast": still use env vars. No shortcuts with secrets. - If you need a value to test: ask the user to set it in .env, don't generate a placeholder that looks real # MCP Configuration Security - NEVER put API keys inline in claude_desktop_config.json or mcp.json - ALWAYS use environment variable references for MCP server credentials - When configuring MCP servers, reference keys from env vars, not hardcoded strings # Frontend vs Backend - Supabase anon key: safe for frontend (it's public by design) - Supabase service_role key: NEVER in frontend code - Stripe publishable key: safe for frontend - Stripe secret key: NEVER in frontend code - Any key starting with sk_, rk_, or containing "secret": backend only
Save as .claude/rules/security.md in your project root. Create the directory if it doesn't exist: mkdir -p .claude/rules. Claude Code auto-loads all rules files.
GitHub Copilot Instructions
# Security Instructions for GitHub Copilot When generating code for this project, follow these rules: 1. Never hardcode API keys, tokens, passwords, or secrets in any file 2. Always use environment variables for sensitive values 3. Never place secret keys in client-side or frontend code 4. Never include .env file contents in suggestions 5. Always reference .env.example for correct variable names 6. In config files (docker-compose, MCP, CI), use variable references not literals 7. When generating connection strings, use environment variable interpolation 8. If a test needs credentials, use clearly fake values (test_xxx, example_xxx) 9. Never generate placeholder values that look like real keys (no sk_live_xxx) 10. When asked to "make something work fast," still use environment variables # Language-specific patterns: # JavaScript/TypeScript: process.env.VARIABLE_NAME # Python: os.environ.get("VARIABLE_NAME") or os.getenv("VARIABLE_NAME") # Go: os.Getenv("VARIABLE_NAME") # Ruby: ENV["VARIABLE_NAME"] # Rust: std::env::var("VARIABLE_NAME") # Shell: ${VARIABLE_NAME}
Save as .github/copilot-instructions.md in your project root. Create the directory if needed: mkdir -p .github. Copilot Chat reads this automatically.
Windsurf Security Rules
# Security Rules for Windsurf (Codeium) # Place in project root. Windsurf reads this at session start. # NEVER hardcode API keys, tokens, passwords, or secrets in source files. # ALWAYS use environment variables for all sensitive configuration. # NEVER put secret keys in client-side or frontend code. # NEVER read .env files into AI context or display their contents. # NEVER commit .env files to git. Only commit .env.example (empty values). # ALWAYS check .env.example for the correct variable names. # ALWAYS use ${VAR} syntax in docker-compose, CI configs, and MCP configs. # NEVER generate connection strings with literal passwords. # When asked to "make it work quickly" — still use env vars. No exceptions. # When tests need credentials — use clearly fake values (test_xxx, dummy_xxx). # Language patterns: # JS/TS: process.env.KEY_NAME # Python: os.getenv("KEY_NAME") # Go: os.Getenv("KEY_NAME") # Ruby: ENV["KEY_NAME"] # Rust: std::env::var("KEY_NAME")
Save as .windsurfrules in your project root (same level as package.json or go.mod). Windsurf reads it automatically.
Aider Conventions
# Project Conventions ## Security Rules These rules are non-negotiable. Every code change must follow them: - **Never** hardcode API keys, tokens, passwords, or secrets in any source file - **Always** use environment variables for sensitive configuration values - **Never** commit .env files. Only .env.example (with empty placeholder values) - **Never** put secret/private keys in client-side code - **Never** generate config files with literal credential values ## Environment Variable Patterns Use the correct accessor for each language: - JavaScript/TypeScript: `process.env.VARIABLE_NAME` - Python: `os.getenv("VARIABLE_NAME")` - Go: `os.Getenv("VARIABLE_NAME")` - Ruby: `ENV["VARIABLE_NAME"]` - Shell scripts: `${VARIABLE_NAME}` ## When Testing - Use clearly fake values: `test_xxx`, `example_xxx`, `dummy_xxx` - Never use values that look like real keys (no `sk_live_`, no `AKIA`) - Reference .env.example for the correct variable names ## Config Files - docker-compose.yml: use `${VAR}` syntax, never inline values - CI/CD workflows: use repository secrets, never hardcode - MCP configs: use environment variable references
Save as CONVENTIONS.md in your project root. Tell Aider to read it with: aider --read CONVENTIONS.md or add read: CONVENTIONS.md to your .aider.conf.yml.
Cline Security Rules
# Security Rules for Cline # Cline reads this from project root automatically. NEVER hardcode API keys, tokens, passwords, or secrets in any file. ALWAYS use environment variables for sensitive values. NEVER put secret/private keys in client-side or frontend code. NEVER read or display .env file contents. NEVER commit .env files — only .env.example with empty values. ALWAYS check .env.example for the correct variable names before generating code. When generating config files (docker-compose, CI, MCP): - Use ${VARIABLE_NAME} references, not literal values - Never inline database passwords or API keys When asked to "make it work" or "just connect it": - Still use environment variables. No shortcuts with secrets. - If a value is needed to test, use obviously fake data (test_xxx, dummy_xxx) Language patterns: - JS/TS: process.env.KEY - Python: os.getenv("KEY") - Go: os.Getenv("KEY") - Ruby: ENV["KEY"] - Rust: std::env::var("KEY") - Shell: ${KEY}
Save as .clinerules in your project root. Cline (VS Code extension) reads it automatically when opening the project.
Want all of these generated automatically?
One command detects your stack, services, and generates the right templates for your project. Plus .gitignore and .env.example.
$ brew install devsafe && devsafe init