Pattern
safety
security

Safety Rails

Secrets management, destructive command prevention, dependency pinning, and other safety practices.

Why Safety Rails Matter

AI can generate and execute code quickly. Without guardrails:

  • Secrets get exposed
  • Files get deleted
  • Dependencies break
  • Production gets affected

Secret Protection

Never Commit Secrets

Add to .gitignore:

gitignore
.env
.env.local
.env.*.local
*.pem
*.key
secrets.json
credentials.json

Environment Variables

Use .env.example as a template:

bash
# .env.example - Safe to commit
DATABASE_URL=postgresql://user:password@localhost:5432/db
API_KEY=your-api-key-here

Never put real values in example files.

Secret Detection

Add pre-commit hook to detect secrets:

bash
#!/bin/bash
# .husky/pre-commit

# Check for common secret patterns
if git diff --cached | grep -E '(api[_-]?key|password|secret|token)\s*[:=]\s*['\''"][^'\''"]' -i; then
  echo "ERROR: Possible secret detected in commit"
  exit 1
fi

Prompting Safely

Safe API Request

engineer

Request code that uses environment variables

Add API integration for [service].

Requirements:
- All credentials from environment variables
- Never hardcode secrets
- Use process.env.VARIABLE_NAME
- Add to .env.example with placeholder values

Destructive Command Prevention

Dangerous Commands

Commands AI should NEVER run unsupervised:

CommandRisk
rm -rfDelete everything
git push --forceRewrite history
git reset --hardLose work
DROP TABLEData loss
chmod 777Security hole

Allowlist Approach

In AGENTS.md:

markdown
## Allowed Commands
- npm run [script]
- git status/diff/log
- cat/less for reading
- mkdir for creating directories

## Forbidden Commands
- rm -rf (especially with wildcards)
- git push --force
- Any command with sudo
- chmod with 777
- Commands with | rm

Confirmation Patterns

AI should confirm before:

  • Deleting files
  • Modifying production configs
  • Running migrations
  • Installing global packages

Dependency Pinning

Lock Files

Always commit lock files:

  • package-lock.json (npm)
  • yarn.lock (yarn)
  • pnpm-lock.yaml (pnpm)

Exact Versions

In package.json:

json
{
  "dependencies": {
    "next": "15.1.0",
    "react": "19.0.0"
  }
}

Avoid:

json
{
  "dependencies": {
    "next": "^15.1.0",
    "react": "*"
  }
}

New Dependency Checklist

Before accepting AI-suggested dependencies:

  • Is it actively maintained?
  • Does it have security vulnerabilities?
  • Is it necessary or is there a built-in alternative?
  • What's the bundle size impact?

Use:

bash
npm audit
npx bundlephobia-cli [package]

File System Safety

Read-Only by Default

Configure AI tools to be read-only initially:

json
// .claude/settings.json
{
  "permissions": {
    "files": {
      "read": ["**/*"],
      "write": ["src/**/*", "tests/**/*"],
      "deny": ["node_modules/**", ".env*"]
    }
  }
}

Backup Before Modify

For critical files:

bash
# Before making changes
cp important-file.ts important-file.ts.bak

Git as Safety Net

Commit before risky operations:

bash
git add .
git commit -m "Checkpoint before [risky operation]"

Production Safety

Environment Separation

typescript
// Only run in development
if (process.env.NODE_ENV !== 'production') {
  // Risky debug code
}

Feature Flags

For new AI-generated features:

typescript
if (process.env.FEATURE_NEW_THING === 'true') {
  // New code path
}

Rollback Plan

Before deploying AI-generated changes:

  1. Know how to rollback
  2. Have monitoring in place
  3. Deploy during low-traffic periods
  4. Start with canary deployment

Verification Checklist

Before committing AI-generated code:

  • No hardcoded secrets
  • No destructive commands
  • Dependencies are pinned
  • Tests pass
  • Lint passes
  • No unnecessary file changes

Safety Configuration

Pre-Commit Hooks

bash
#!/bin/bash
# Run all safety checks

npm run lint
npm run typecheck
npm run test

# Check for secrets
git secrets --scan

# Check dependencies
npm audit --audit-level=high

CI Safety

yaml
# .github/workflows/safety.yml
name: Safety Check
on: [push, pull_request]

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm audit --audit-level=high
      - run: npx secretlint "**/*"