security-operations-deployment
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".
What this skill does
# 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:**
```typescript
// Order matters: rate limit first, then CSRF
export const POST = withRateLimit(withCsrf(handler));
```
**Why order matters:**
1. Rate limiting runs first to block excessive requests early
2. CSRF verification runs on requests that pass rate limiting
3. 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):**
```bash
# 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):**
```bash
# 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
```bash
# 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.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
```typescript
// 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_SECRET` generated and configured (32+ bytes)
- [ ] `SESSION_SECRET` generated 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.local` NOT committed to git (check with `git 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.json` committed to git
- [ ] Next.js on latest stable version (currently 15.5.4+)
- [ ] All critical packages updated
### Security Features
- [ ] CSRF protection tested (see `security-testing` skill)
- [ ] 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
```bash
# 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=Related in Security
mac-ops
IncludedComprehensive macOS workstation operations — diagnose kernel panics, identify failing drives, audit launchd startup items, decode wake reasons, triage TCC permission denials, manage APFS snapshots, recover from no-boot. Use for: Mac is slow, slow bootup, won't boot, kernel panic, kernel_task hot, mds_stores CPU, photoanalysisd, cloudd, login loop, gray screen, sleep wake failure, drive failing, IO errors, APFS snapshots eating space, Time Machine local snapshots, Spotlight indexing, launchd, LaunchAgent, LaunchDaemon, login items, TCC permissions, Full Disk Access, Screen Recording denied, Gatekeeper, quarantine, com.apple.quarantine, app is damaged, helper tool, /Library/PrivilegedHelperTools, pmset, wake reasons, dark wake, sysdiagnose, panic.ips, DiagnosticReports, configuration profile, MDM profile, remote diagnostics over SSH.
a11y-audit
IncludedRun accessibility audits on web projects combining automated scanning (axe-core, Lighthouse) with WCAG 2.1 AA compliance mapping, manual check guidance, and structured reporting. Output is configurable: markdown report only, markdown plus machine-readable JSON, or markdown plus issue tracker integration. Use this skill whenever the user mentions "accessibility audit", "a11y audit", "WCAG audit", "accessibility check", "compliance scan", or asks to check a web project for accessibility issues. Also trigger when the user wants to verify WCAG conformance or map findings to a specific standard (CAN-ASC-6.2, EN 301 549, ADA/AODA).
erpclaw
IncludedAI-native ERP system with self-extending OS. Full accounting, invoicing, inventory, purchasing, tax, billing, HR, payroll, advanced accounting (ASC 606/842, intercompany, consolidation), and financial reporting. 413 actions across 14 domains, 43 expansion modules. Constitutional guardrails, adversarial audit, schema migration. Double-entry GL, immutable audit trail, US GAAP.
assess
IncludedAssesses and rates quality 0-10 across multiple dimensions (correctness, maintainability, security, performance, testability, simplicity) with pros/cons analysis. Compares against project conventions and prior decisions from memory. Produces structured evaluation reports with actionable improvement suggestions. Use when evaluating code, designs, architectures, or comparing alternative approaches.
spring-boot-security-jwt
IncludedProvides JWT authentication and authorization patterns for Spring Boot 3.5.x covering token generation with JJWT, Bearer/cookie authentication, database/OAuth2 integration, and RBAC/permission-based access control using Spring Security 6.x. Use when implementing authentication or authorization in Spring Boot applications.
code-hardcode-audit
IncludedDetect hardcoded values, magic numbers, and leaked secrets. TRIGGERS - hardcode audit, magic numbers, PLR2004, secret scanning.