security-operations-deployment
About
This skill provides operational security guidance for application deployment and maintenance. It helps developers select appropriate middlewares, configure environment variables, and implement security monitoring in production. Use it for pre-deployment checklists and securing endpoints against common threats like rate limiting and abuse.
Documentation
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:
// Order matters: rate limit first, then CSRF
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 Protection
# Generate with: node -p "require('crypto').randomBytes(32).toString('base64url')"
CSRF_SECRET=<32-byte-base64url-string>
SESSION_SECRET=<32-byte-base64url-string>
# Clerk Authentication (from Clerk dashboard)
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 Database (from Convex dashboard)
CONVEX_DEPLOYMENT=dev:...
NEXT_PUBLIC_CONVEX_URL=https://...convex.cloud
# Optional: Stripe (if using direct Stripe, not Clerk Billing)
STRIPE_SECRET_KEY=sk_test_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
# Optional: Clerk Webhook Secret
CLERK_WEBHOOK_SECRET=whsec_...
Production (Vercel/hosting platform):
# CSRF Protection (different from dev!)
CSRF_SECRET=<different-32-byte-string>
SESSION_SECRET=<different-32-byte-string>
# Clerk Production Keys
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 Production
CONVEX_DEPLOYMENT=prod:...
NEXT_PUBLIC_CONVEX_URL=https://...convex.cloud
# Optional: Stripe Production
STRIPE_SECRET_KEY=sk_live_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...
# Optional: Clerk Webhook Secret (production)
CLERK_WEBHOOK_SECRET=whsec_...
Generating Secrets
# Generate CSRF_SECRET (32 bytes)
node -p "require('crypto').randomBytes(32).toString('base64url')"
# Generate SESSION_SECRET (32 bytes)
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.localto.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.localto version control - Log environment variables
- Expose secrets in client-side code
- Use
.env.localvalues inNEXT_PUBLIC_*variables (they're exposed to browser!) - Share secrets via email, Slack, or insecure channels
Validating Configuration on Startup
// lib/config.ts
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(', ')}`);
}
// Validate secret lengths
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');
}
}
// In your app startup (e.g., middleware.ts or layout.tsx)
validateConfig();
Pre-Deployment Security Checklist
Run through this checklist before every production deployment:
Environment & Configuration
- All environment variables set in production environment
-
CSRF_SECRETgenerated and configured (32+ bytes) -
SESSION_SECRETgenerated and configured (32+ bytes) - Clerk production keys configured (
pk_live_...,sk_live_...) - Convex production deployment configured
- Stripe live mode keys configured (if using direct Stripe)
-
.env.localNOT committed to git (check withgit status) - Different secrets used for dev vs production
Dependencies
- Run
npm audit --production- 0 vulnerabilities - Run
npm outdated- Check for critical security updates -
package-lock.jsoncommitted to git - Next.js on latest stable version (currently 15.5.4+)
- All critical packages updated
Security Features
- CSRF protection tested (see
security-testingskill) - Rate limiting tested (
node scripts/test-rate-limit.js) - Input validation tested with malicious input
- Security headers verified (
curl -I https://yourapp.com) - HSTS enabled in production (automatic in middleware)
- Error messages are generic in production (no stack traces)
Authentication & Authorization
- Protected routes require authentication
- Resource ownership checked before access
- Subscription status verified for premium features
- Webhook signatures verified (Clerk, Stripe)
- Session expiration handled gracefully
- No hardcoded credentials in code
API Security
- All POST/PUT/DELETE routes have CSRF protection
- All public endpoints have rate limiting
- All user input validated with Zod schemas
- All errors handled with error handler utilities
- No sensitive data in logs (passwords, tokens, cards, PII)
- No hardcoded secrets in code (grep check below)
Payment Security (if applicable)
- Using Clerk Billing + Stripe (not handling cards directly)
- Webhooks verified with Svix signatures
- Subscription status checked on server
- Test mode disabled in production
- No card data logged anywhere
Testing
- Rate limit test passes:
node scripts/test-rate-limit.js - CSRF protection tested manually
- Input validation tested with XSS payloads
- Security headers checked:
curl -I https://yourapp.com - Authentication flows tested
- Error handling tested in production mode
Final Checks
# Check for hardcoded secrets
grep -r "sk_live" . --exclude-dir=node_modules
grep -r "AKIA" . --exclude-dir=node_modules
grep -r "api_key.*=" . --exclude-dir=node_modules
# Verify .env.local not in git
git status | grep .env.local # Should return nothing
# Run full security audit
npm audit --production
bash scripts/security-check.sh
# Test production build
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)
# View logs in Vercel dashboard
https://vercel.com/your-project/logs
# Filter by status code
Status: 429 # Rate limited
Status: 403 # CSRF/Forbidden
Status: 401 # Unauthorized
Clerk Dashboard (Authentication)
Monitor in Clerk dashboard:
- Failed sign-in attempts
- Account creation rate
- Session activity
- Suspicious IP addresses
Custom Logging
// lib/security-logger.ts
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
};
// In production, send to logging service
if (process.env.NODE_ENV === 'production') {
console.log(JSON.stringify(log));
// Optional: Send to external service (Datadog, LogRocket, etc.)
} else {
console.log('Security Event:', log);
}
}
// Usage in middleware/routes
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:
// Monitor and alert on patterns
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 featuresdocs/security/SECURITY_IMPLEMENTATION.md- Complete implementation guideREADME.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 verificationscripts/security-check.sh- Dependency auditscripts/security-test.sh- Comprehensive security test suite (if created)
Example Implementations:
app/api/example-protected/route.ts- Complete security stack exampleapp/api/test-rate-limit/route.ts- Rate limiting test endpointapp/api/csrf/route.ts- CSRF token generation
External Security Resources
OWASP (Security Standards):
- OWASP Top 10 2021: https://owasp.org/www-project-top-ten/
- OWASP Cheat Sheet Series: https://cheatsheetseries.owasp.org
- OWASP API Security Top 10: https://owasp.org/www-project-api-security/
Framework & Service Docs:
- Next.js Security: https://nextjs.org/docs/app/guides/security
- Clerk Security: https://clerk.com/docs/security
- Convex Security: https://docs.convex.dev/production/hosting/authentication
- Stripe Security: https://stripe.com/docs/security
Testing Tools:
- Security Headers Scanner: https://securityheaders.com/
- Mozilla Observatory: https://observatory.mozilla.org/
- SSL Labs Test: https://www.ssllabs.com/ssltest/
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
# Generate secrets
node -p "require('crypto').randomBytes(32).toString('base64url')"
# Check for vulnerabilities
npm audit --production
# Check for outdated packages
npm outdated
# Run security test suite
node scripts/test-rate-limit.js
bash scripts/security-check.sh
# Check for hardcoded secrets
grep -r "sk_live" . --exclude-dir=node_modules
grep -r "AKIA" . --exclude-dir=node_modules
# Test security headers
curl -I https://yourapp.com
# Verify .env.local not committed
git status | grep .env.local
# Production build test
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.
Quick Install
/plugin add https://github.com/harperaa/secure-claude-skills/tree/main/security-operationsCopy and paste this command in Claude Code to install this skill
GitHub 仓库
Related Skills
sglang
MetaSGLang is a high-performance LLM serving framework that specializes in fast, structured generation for JSON, regex, and agentic workflows using its RadixAttention prefix caching. It delivers significantly faster inference, especially for tasks with repeated prefixes, making it ideal for complex, structured outputs and multi-turn conversations. Choose SGLang over alternatives like vLLM when you need constrained decoding or are building applications with extensive prefix sharing.
evaluating-llms-harness
TestingThis Claude Skill runs the lm-evaluation-harness to benchmark LLMs across 60+ standardized academic tasks like MMLU and GSM8K. It's designed for developers to compare model quality, track training progress, or report academic results. The tool supports various backends including HuggingFace and vLLM models.
llamaguard
OtherLlamaGuard is Meta's 7-8B parameter model for moderating LLM inputs and outputs across six safety categories like violence and hate speech. It offers 94-95% accuracy and can be deployed using vLLM, Hugging Face, or Amazon SageMaker. Use this skill to easily integrate content filtering and safety guardrails into your AI applications.
langchain
MetaLangChain is a framework for building LLM applications using agents, chains, and RAG pipelines. It supports multiple LLM providers, offers 500+ integrations, and includes features like tool calling and memory management. Use it for rapid prototyping and deploying production systems like chatbots, autonomous agents, and question-answering services.
