---
trigger: always_on
---


# Security Patterns for GoodGo Microservices

## When to Use This Skill

Use this skill when:
- Implementing authentication and authorization in any service
- Protecting sensitive data (PII, credentials, tokens)
- Validating user inputs and file uploads
- Implementing rate limiting and DDoS protection
- Setting up audit logging and security monitoring
- Encrypting data at rest and in transit
- Managing secrets and credentials
- Implementing security testing
- Handling security incidents
- Designing secure API endpoints

## Core Security Principles

1. **Defense in Depth**: Multiple layers of security controls
2. **Least Privilege**: Grant minimum required permissions
3. **Fail Secure**: Default to deny access
4. **Separation of Duties**: Critical operations require multiple approvals
5. **Audit Everything**: Log all security-relevant events
6. **Encrypt Sensitive Data**: PII, tokens, credentials must be encrypted
7. **Validate All Inputs**: Never trust user input
8. **Principle of Least Exposure**: Minimize attack surface
9. **Secure by Default**: Security built-in, not bolted on
10. **Assume Breach**: Design for detection and response

## Authentication & Authorization

### JWT Token Validation

Extract tokens from Authorization header or cookies, verify with `jwtService.verifyAccessToken()`, and attach user payload to request. Return 401 for missing/invalid tokens.

```typescript
// Key pattern - see references/REFERENCE.md for full implementation
const authHeader = req.headers.authorization;
const token = authHeader?.startsWith('Bearer ') ? authHeader.substring(7) : req.cookies?.access_token;
const payload = await jwtService.verifyAccessToken(token);
req.user = { id: payload.sub, roles: payload.roles || [], permissions: payload.permissions || [] };
```

### Role-Based Authorization (RBAC)

Use `requireRole()` middleware for role checks and `requirePermission()` for fine-grained access control with `resource:action` format.

```typescript
// Usage pattern
router.post('/api/v1/users', authenticate(), requirePermission('users', 'create'), userController.create);
router.delete('/api/v1/admin', authenticate(), requireRole('admin', 'superadmin'), adminController.delete);
```

### Resource Ownership

Validate users can only access their own resources using `requireOwnership()` middleware.

## Data Protection

### Encryption

- Use AES-256-GCM for encrypting PII at rest
- Store encrypted data as `iv:tag:ciphertext` format
- Require 32+ character ENCRYPTION_KEY

### Password Hashing

- Always use bcrypt with cost factor 12 in production
- Never log passwords - sanitize before logging

### Token Storage

- Hash tokens with SHA-256 before database storage
- Use `crypto.randomBytes(32)` for secure token generation

## Input Validation

### Zod Schema Validation

Always validate inputs with Zod schemas before processing:

```typescript
const CreateUserDto = z.object({
  email: z.string().email(),
  password: z.string().min(8).regex(/[A-Z]/).regex(/[a-z]/).regex(/[0-9]/).regex(/[^A-Za-z0-9]/),
  phone: z.string().regex(/^\+[1-9]\d{1,14}$/).optional(),
  name: z.string().min(1).max(255)
});

// In controller
const dto = CreateUserDto.parse(req.body);
```

### File Upload Validation

- Check file size (max 10MB default)
- Validate MIME type against whitelist
- Verify content with `file-type` library to prevent MIME spoofing

### SQL Injection Prevention

Always use Prisma parameterized queries - never string concatenation for queries.

## Rate Limiting

Configure Redis-backed rate limiting for all endpoints:

| Limiter Type | Window | Max Requests | Use Case |
|-------------|--------|--------------|----------|
| Standard | 15 min | 100 | General API endpoints |
| Strict | 1 hour | 10 | Sensitive operations |
| Login | 15 min | 5 | Authentication endpoints |

```typescript
router.post('/api/v1/auth/login', loginLimiter, authController.login);
```

## Security Headers

Use Helmet middleware with CSP, HSTS, and additional headers:
- `X-Content-Type-Options: nosniff`
- `X-Frame-Options: DENY`
- `X-XSS-Protection: 1; mode=block`
- `Referrer-Policy: strict-origin-when-cross-origin`

## CORS Configuration

- Whitelist allowed origins from environment variables
- Enable credentials for authenticated requests
- Set `maxAge: 86400` (24 hours) for preflight caching

## Secrets Management

- Never hardcode secrets - use environment variables
- Validate secrets with Zod schema at startup
- Use secret managers in production (AWS Secrets Manager, Vault, etc.)
- Rotate secrets quarterly

```typescript
const secretsSchema = z.object({
  JWT_SECRET: z.string().min(32),
  DATABASE_URL: z.string().url(),
  ENCRYPTION_KEY: z.string().min(32).optional()
});
```

## Audit Logging

Log all security-relevant events with sanitized details:

```typescript
await auditService.logSecurityEvent('LOGIN_SUCCESS', user.id, { email: user.email }, req);
await auditService.logSecurityEvent('PERMISSION_DENIED', user.id, { resource, action }, req);
```

Sanitize sensitive fields: password, token, secret, ssn, creditCard.

## Error Handling

- Log full errors internally
- Never expose user existence (use generic "Invalid credentials")
- Show stack traces only in development
- Return sanitized error codes in production

## Security Testing

Write tests for:
- SQL injection prevention
- XSS attack prevention
- Authentication enforcement
- Authorization enforcement
- Rate limiting effectiveness

## Best Practices

- All endpoints require authentication (except public)
- Authorization checks at every protected route
- Input validation with Zod on all user input
- Rate limiting on all endpoints
- Error messages sanitized in production
- PII encrypted at rest with AES-256-GCM
- Passwords hashed with bcrypt (cost 12+)
- Tokens hashed before database storage
- HTTPS enforced (TLS 1.2+)
- Security headers via Helmet
- Audit logging for security events
- Dependencies scanned for vulnerabilities
- File uploads validated (size, type, content)

## Common Mistakes

### 1. Weak Password Hashing

```typescript
// BAD: Low cost factor
const hash = await bcrypt.hash(password, 8);

// GOOD: Use cost 12
const hash = await bcrypt.hash(password, 12);
```

### 2. Hardcoded Secrets

```typescript
// BAD
const JWT_SECRET = "my-secret-key";

// GOOD
const JWT_SECRET = process.env.JWT_SECRET;
if (!JWT_SECRET) throw new Error('JWT_SECRET required');
```

### 3. Missing Input Validation

```typescript
// BAD
const user = await prisma.user.findUnique({ where: { id: req.params.id } });

// GOOD
const { id } = z.object({ id: z.string().cuid() }).parse(req.params);
const user = await prisma.user.findUnique({ where: { id } });
```

### 4. Logging Sensitive Data

```typescript
// BAD
logger.info('User login', { email, password });

// GOOD
logger.info('User login', { email, password: '[REDACTED]' });
```

### 5. Exposing User Existence

```typescript
// BAD
if (!user) throw new Error('User not found');

// GOOD
if (!user || !await bcrypt.compare(password, user.passwordHash)) {
  throw new Error('Invalid credentials');
}
```

## Quick Reference

| Security Area | Implementation |
|--------------|----------------|
| **Password hashing** | `bcrypt.hash(password, 12)` |
| **JWT Access Token** | 15 minutes expiry |
| **JWT Refresh Token** | 7 days expiry |
| **Rate limiting** | Standard: 100/15min, Strict: 10/hour, Login: 5/15min |
| **Encryption** | AES-256-GCM for PII |
| **Input validation** | Zod schemas, always parse before use |
| **SQL injection** | Use Prisma (parameterized by default) |
| **Security headers** | helmet middleware |
| **CORS** | Whitelist origins, credentials: true |

**Essential Imports:**

```typescript
import bcrypt from 'bcrypt';
import helmet from 'helmet';
import rateLimit from 'express-rate-limit';
import { z } from 'zod';
import { jwtService } from '@goodgo/auth-sdk';
```

## Security Checklist

Before deploying any service:

- [ ] All endpoints require authentication (except public)
- [ ] Authorization checks implemented (RBAC/ABAC)
- [ ] Input validation with Zod schemas
- [ ] Rate limiting configured
- [ ] Error messages sanitized (no info disclosure)
- [ ] PII encrypted at rest
- [ ] Passwords hashed with bcrypt (cost 12+)
- [ ] Tokens hashed before storing
- [ ] Secrets in environment variables (never hardcoded)
- [ ] HTTPS enforced (TLS 1.2+)
- [ ] CORS configured correctly
- [ ] Security headers set (helmet)
- [ ] Audit logging enabled
- [ ] SQL injection prevented (use Prisma)
- [ ] XSS prevention (input sanitization)
- [ ] File upload validation
- [ ] Security tests passing
- [ ] Dependencies scanned for vulnerabilities
- [ ] Secrets rotation plan in place

## Resources

- [Detailed Code Examples](./references/REFERENCE.md) - Full implementation examples
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [OWASP API Security Top 10](https://owasp.org/www-project-api-security/)
- [Node.js Security Best Practices](https://nodejs.org/en/docs/guides/security/)
- [Express Security Best Practices](https://expressjs.com/en/advanced/best-practice-security.html)
