| name | security-operations-deployment |
| description | Operational security guidance for deployment, monitoring, and maintenance. Use this skill when you need to understand which middlewares to apply, configure environment variables, monitor security post-deployment, or follow the pre-deployment checklist. Triggers include "security operations", "deployment security", "security monitoring", "environment variables", "when to use middleware", "pre-deployment", "security checklist", "production security". |
Security Operations & Deployment
When to Apply Each Middleware - Decision Guide
withRateLimit() - Apply to:
✅ Always apply to:
- Any route that could be abused (spam, brute force)
- Login-like operations (even if Clerk handles auth)
- Data creation/modification endpoints
- Contact/support form endpoints
- Webhooks (to prevent DoS)
- File upload endpoints
- Search endpoints
- Data export endpoints
- Any expensive AI/API operations
- Report generation
- Bulk operations
❌ Usually not needed for:
- Static asset requests (handled by CDN)
- Simple GET endpoints that only read public data
- Health check endpoints
- Endpoints already protected by authentication rate limits
withCsrf() - Apply to:
✅ Always apply to:
- All POST/PUT/DELETE operations
- Any state-changing operation
- Form submissions
- Account modifications
- Payment operations
- Data deletion operations
❌ Skip for:
- GET requests (read-only operations)
- Public read-only endpoints
- Webhooks (use signature verification instead)
Combining Both Middlewares
For maximum protection:
export const POST = withRateLimit(withCsrf(handler));
Why order matters:
- Rate limiting runs first to block excessive requests early
- CSRF verification runs on requests that pass rate limiting
- More efficient: don't waste CSRF verification on rate-limited requests
Decision Matrix:
| Route Type | Rate Limit | CSRF | Authentication |
|---|
| Public form submission | ✅ Yes | ✅ Yes | ❌ No |
| Protected data modification | ✅ Yes | ✅ Yes | ✅ Yes |
| Public read-only API | ❌ No | ❌ No | ❌ No |
| Protected read-only API | ✅ Maybe | ❌ No | ✅ Yes |
| Webhook endpoint | ✅ Yes | ❌ No | ✅ Signature |
| File upload | ✅ Yes | ✅ Yes | ✅ Yes |
Environment Variables & Secrets
Required Environment Variables for This Project
Development (.env.local - NEVER commit):
CSRF_SECRET=<32-byte-base64url-string>
SESSION_SECRET=<32-byte-base64url-string>
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
NEXT_PUBLIC_CLERK_FRONTEND_API_URL=https://your-app.clerk.accounts.dev
CONVEX_DEPLOYMENT=dev:...
NEXT_PUBLIC_CONVEX_URL=https://...convex.cloud
STRIPE_SECRET_KEY=sk_test_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
CLERK_WEBHOOK_SECRET=whsec_...
Production (Vercel/hosting platform):
CSRF_SECRET=<different-32-byte-string>
SESSION_SECRET=<different-32-byte-string>
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_...
CLERK_SECRET_KEY=sk_live_...
NEXT_PUBLIC_CLERK_FRONTEND_API_URL=https://your-app.clerk.accounts.com
CONVEX_DEPLOYMENT=prod:...
NEXT_PUBLIC_CONVEX_URL=https://...convex.cloud
STRIPE_SECRET_KEY=sk_live_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...
CLERK_WEBHOOK_SECRET=whsec_...
Generating Secrets
node -p "require('crypto').randomBytes(32).toString('base64url')"
node -p "require('crypto').randomBytes(32).toString('base64url')"
Environment Variable Best Practices
✅ DO:
- Use different secrets for dev/staging/production
- Generate strong random secrets (32+ bytes)
- Add
.env.local to .gitignore
- Store production secrets in hosting platform's secret manager
- Rotate secrets quarterly
- Validate required environment variables on startup
❌ NEVER:
- Hardcode API keys, tokens, or secrets in code
- Commit
.env.local to version control
- Log environment variables
- Expose secrets in client-side code
- Use
.env.local values in NEXT_PUBLIC_* variables (they're exposed to browser!)
- Share secrets via email, Slack, or insecure channels
Validating Configuration on Startup
const requiredEnvVars = [
'CSRF_SECRET',
'SESSION_SECRET',
'NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY',
'CLERK_SECRET_KEY',
'NEXT_PUBLIC_CONVEX_URL'
];
export function validateConfig() {
const missing = requiredEnvVars.filter(v => !process.env[v]);
if (missing.length > 0) {
throw new Error(`Missing required environment variables: ${missing.join(', ')}`);
}
if (process.env.CSRF_SECRET && process.env.CSRF_SECRET.length < 32) {
throw new Error('CSRF_SECRET must be at least 32 characters');
}
if (process.env.SESSION_SECRET && process.env.SESSION_SECRET.length < 32) {
throw new Error('SESSION_SECRET must be at least 32 characters');
}
}
validateConfig();
Pre-Deployment Security Checklist
Run through this checklist before every production deployment:
Environment & Configuration
Dependencies
Security Features
Authentication & Authorization
API Security
Payment Security (if applicable)
Testing
Final Checks
grep -r "sk_live" . --exclude-dir=node_modules
grep -r "AKIA" . --exclude-dir=node_modules
grep -r "api_key.*=" . --exclude-dir=node_modules
git status | grep .env.local
npm audit --production
bash scripts/security-check.sh
npm run build
NODE_ENV=production npm start
Security Monitoring Post-Deployment
What to Monitor
Server Logs (Daily)
Monitor for these patterns that indicate potential attacks:
Rate Limit Violations (HTTP 429):
- Repeated 429 errors from same IP → potential abuse/brute force
- High volume of 429s → possible distributed attack
- 429s on login endpoints → credential stuffing attempt
CSRF Failures (HTTP 403):
- Repeated 403 with "CSRF token invalid" → potential CSRF attack
- Sudden spike in CSRF failures → possible automated attack
- 403s without prior token fetch → attack bypass attempt
Authentication Failures (HTTP 401/403):
- 401 spikes → potential brute force on protected endpoints
- 403 spikes → unauthorized access attempts
- Pattern of 401 followed by 403 → enumeration attack
Unusual Error Patterns:
- Sudden increase in 500 errors → potential attack or system issue
- 400 errors with validation failures → input attack attempts
- Errors from unusual geographic locations
Metrics to Track (Weekly)
Authentication Metrics:
- Failed authentication attempts per hour
- Account lockouts (if implemented)
- Geographic distribution of login attempts
- Unusual login times (3am mass logins = bot)
Rate Limiting Metrics:
- Rate limit violations per IP
- Top IPs hitting rate limits
- Endpoints most frequently rate-limited
- Rate limit violation trends over time
CSRF Protection Metrics:
- CSRF validation failures
- CSRF token generation rate
- Token reuse attempts
- Missing token attempts
Input Validation Metrics:
- Validation failures by field
- XSS attempt patterns (script tags in input)
- SQL injection attempt patterns
- Excessive input length attempts
Error Rate Metrics:
- Error rates by endpoint
- Error rates by HTTP status code
- Error rate trends over time
- Geographic distribution of errors
Setting Up Monitoring
Vercel Logs (Built-in)
https://vercel.com/your-project/logs
Status: 429
Status: 403
Status: 401
Clerk Dashboard (Authentication)
Monitor in Clerk dashboard:
- Failed sign-in attempts
- Account creation rate
- Session activity
- Suspicious IP addresses
Custom Logging
export function logSecurityEvent(event: {
type: 'RATE_LIMIT' | 'CSRF_FAILURE' | 'AUTH_FAILURE' | 'VALIDATION_FAILURE';
ip?: string;
userId?: string;
endpoint?: string;
details?: Record<string, any>;
}) {
const log = {
timestamp: new Date().toISOString(),
environment: process.env.NODE_ENV,
...event
};
if (process.env.NODE_ENV === 'production') {
console.log(JSON.stringify(log));
} else {
console.log('Security Event:', log);
}
}
if (rateLimitExceeded) {
logSecurityEvent({
type: 'RATE_LIMIT',
ip: clientIp,
endpoint: request.nextUrl.pathname
});
}
Response Procedures
High-Priority Alerts (Immediate Response):
- Massive spike in failed authentication (>100/min)
- CSRF failures from many IPs (coordinated attack)
- Sudden 500 error rate increase (>10x normal)
- Known vulnerability being exploited
Medium-Priority (24-hour Response):
- Gradual increase in rate limit violations
- Single IP with persistent failed auth attempts
- New error patterns in logs
- Unusual traffic from new geographic regions
Low-Priority (Weekly Review):
- Normal background failed auth attempts
- Occasional rate limit hits
- Standard input validation failures
- Routine error patterns
Automated Alerting
Set up alerts in your hosting platform:
Vercel:
Alerts → New Alert Rule
- Error rate > 10% for 5 minutes → Email/Slack
- 429 responses > 100/min → Email/Slack
- 500 responses > 50/min → Email/Slack
Custom Alerts:
if (rateLimitViolations > THRESHOLD) {
await sendAlert({
severity: 'HIGH',
message: `Rate limit violations: ${rateLimitViolations}/min`,
ip: attackerIp
});
}
Resources & Documentation
Project Security Documentation
Implementation Guides:
.claude/skills/security/security-overview/SKILL.md - Overall architecture
.claude/skills/security/*/SKILL.md - Individual security features
docs/security/SECURITY_IMPLEMENTATION.md - Complete implementation guide
README.md - Security Configuration section
Awareness & Learning:
.claude/skills/security/security-awareness/ - AI code vulnerability analysis
.claude/skills/security/security-awareness/awareness-overview/ - Complete security overview
Testing & Verification Scripts
Security Testing:
scripts/test-rate-limit.js - Rate limiting verification
scripts/security-check.sh - Dependency audit
scripts/security-test.sh - Comprehensive security test suite (if created)
Example Implementations:
app/api/example-protected/route.ts - Complete security stack example
app/api/test-rate-limit/route.ts - Rate limiting test endpoint
app/api/csrf/route.ts - CSRF token generation
External Security Resources
OWASP (Security Standards):
Framework & Service Docs:
Testing Tools:
Maintenance Schedule
Daily
- Check error logs in Vercel dashboard
- Monitor Clerk dashboard for failed auth attempts
- Review any security alerts
Weekly
- Run
npm audit --production
- Check GitHub Dependabot alerts
- Review error logs for patterns
- Check rate limit violation trends
Monthly
- Full security audit:
bash scripts/security-check.sh
- Update dependencies:
npm update + test
- Review and rotate any compromised secrets
- Re-run security testing suite
- Check security headers: https://securityheaders.com/
Quarterly
- Rotate CSRF_SECRET and SESSION_SECRET
- Major framework updates (Next.js, React)
- Full penetration test (manual XSS, CSRF, auth bypass attempts)
- Review and update security policies
- Security awareness training (review skills)
Quick Reference Commands
node -p "require('crypto').randomBytes(32).toString('base64url')"
npm audit --production
npm outdated
node scripts/test-rate-limit.js
bash scripts/security-check.sh
grep -r "sk_live" . --exclude-dir=node_modules
grep -r "AKIA" . --exclude-dir=node_modules
curl -I https://yourapp.com
git status | grep .env.local
npm run build
NODE_ENV=production npm start
Summary: Security Operations Principles
🔒 Before Deployment:
- Checklist must be 100% complete
- 0 npm audit vulnerabilities
- All tests passing
- All environment variables configured
🔒 After Deployment:
- Monitor logs daily
- Respond to alerts immediately
- Review metrics weekly
- Update dependencies monthly
🔒 Continuous:
- Security is never "done"
- Stay updated on new vulnerabilities
- Keep dependencies current
- Test security features regularly
For implementation details, refer to individual security skills.
For vulnerability awareness, refer to security-awareness skills.