Complete v0.5.0 implementation: Database (@db-engineer): - 3 migrations: users, api_keys, report_schedules tables - Foreign keys, indexes, constraints, enums Backend (@backend-dev): - JWT authentication service with bcrypt (cost=12) - Auth endpoints: /register, /login, /refresh, /me - API Keys service with hash storage and prefix validation - API Keys endpoints: CRUD + rotate - Security module with JWT HS256 Frontend (@frontend-dev): - Login/Register pages with validation - AuthContext with localStorage persistence - Protected routes implementation - API Keys management UI (create, revoke, rotate) - Header with user dropdown DevOps (@devops-engineer): - .env.example and .env.production.example - docker-compose.scheduler.yml - scripts/setup-secrets.sh - INFRASTRUCTURE_SETUP.md QA (@qa-engineer): - 85 E2E tests: auth.spec.ts, apikeys.spec.ts, scenarios.spec.ts, regression-v050.spec.ts - auth-helpers.ts with 20+ utility functions - Test plans and documentation Architecture (@spec-architect): - SECURITY.md with best practices - SECURITY-CHECKLIST.md pre-deployment - Updated architecture.md with auth flows - Updated README.md with v0.5.0 features Documentation: - Updated todo.md with v0.5.0 status - Added docs/README.md index - Complete setup instructions Dependencies added: - bcrypt, python-jose, passlib, email-validator Tested: JWT auth flow, API keys CRUD, protected routes, 85 E2E tests ready Closes: v0.5.0 milestone
14 KiB
14 KiB
Security Policy - mockupAWS v0.5.0
Version: 0.5.0
Last Updated: 2026-04-07
Status: In Development
Table of Contents
- Security Overview
- Authentication Architecture
- API Keys Security
- Rate Limiting
- CORS Configuration
- Input Validation
- Data Protection
- Security Best Practices
- Incident Response
Security Overview
mockupAWS implements defense-in-depth security with multiple layers of protection:
┌─────────────────────────────────────────────────────────────────────────┐
│ SECURITY LAYERS │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ Layer 1: Network Security │
│ ├── HTTPS/TLS 1.3 enforcement │
│ └── CORS policy configuration │
│ │
│ Layer 2: Rate Limiting │
│ ├── Auth endpoints: 5 req/min │
│ ├── API Key endpoints: 10 req/min │
│ └── General endpoints: 100 req/min │
│ │
│ Layer 3: Authentication │
│ ├── JWT tokens (HS256, 30min access, 7days refresh) │
│ ├── API Keys (hashed storage, prefix identification) │
│ └── bcrypt password hashing (cost=12) │
│ │
│ Layer 4: Authorization │
│ ├── Scope-based API key permissions │
│ └── Role-based access control (RBAC) │
│ │
│ Layer 5: Input Validation │
│ ├── Pydantic request validation │
│ ├── SQL injection prevention │
│ └── XSS protection │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Authentication Architecture
JWT Token Implementation
Token Configuration
| Parameter | Value | Description |
|---|---|---|
| Algorithm | HS256 | HMAC with SHA-256 |
| Secret Length | ≥32 characters | Minimum 256 bits |
| Access Token TTL | 30 minutes | Short-lived for security |
| Refresh Token TTL | 7 days | Longer-lived for UX |
| Token Rotation | Enabled | New refresh token on each use |
Token Structure
{
"sub": "user-uuid",
"exp": 1712592000,
"iat": 1712590200,
"type": "access",
"jti": "unique-token-id"
}
Security Requirements
-
JWT Secret Generation:
# Generate a secure 256-bit secret openssl rand -hex 32 # Store in .env file JWT_SECRET_KEY=your-generated-secret-here-32chars-min -
Secret Storage:
- Never commit secrets to version control
- Use environment variables or secret management
- Rotate secrets periodically (recommended: 90 days)
- Use different secrets per environment
-
Token Validation:
- Verify signature integrity
- Check expiration time
- Validate
sub(user ID) exists - Reject tokens with
type: refreshfor protected routes
Password Security
bcrypt Configuration
| Parameter | Value | Description |
|---|---|---|
| Algorithm | bcrypt | Industry standard |
| Cost Factor | 12 | ~250ms per hash |
| Salt Size | 16 bytes | Random per password |
Password Requirements
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character (!@#$%^&*)
Password Storage
# NEVER store plaintext passwords
# ALWAYS hash before storage
import bcrypt
password_hash = bcrypt.hashpw(
password.encode('utf-8'),
bcrypt.gensalt(rounds=12)
)
API Keys Security
Key Generation
Format: mk_<prefix>_<random>
Example: mk_a3f9b2c1_xK9mP2nQ8rS4tU7vW1yZ
│ │ │
│ │ └── 32 random chars (base64url)
│ └── 8 char prefix (identification)
└── Fixed prefix (mk_)
Storage Security
| Aspect | Implementation | Status |
|---|---|---|
| Storage | Hash only (SHA-256) | ✅ Implemented |
| Transmission | HTTPS only | ✅ Required |
| Prefix | First 8 chars stored plaintext | ✅ Implemented |
| Lookup | By prefix + hash comparison | ✅ Implemented |
⚠️ CRITICAL: The full API key is only shown once at creation. Store it securely!
Scopes and Permissions
Available scopes:
| Scope | Description | Access Level |
|---|---|---|
read:scenarios |
Read scenarios | Read-only |
write:scenarios |
Create/update scenarios | Write |
delete:scenarios |
Delete scenarios | Delete |
read:reports |
Read/download reports | Read-only |
write:reports |
Generate reports | Write |
read:metrics |
View metrics | Read-only |
ingest:logs |
Send logs to scenarios | Special |
API Key Validation Flow
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Request │────>│ Extract Key │────>│ Find by │
│ X-API-Key │ │ from Header │ │ Prefix │
└──────────────┘ └──────────────┘ └──────┬───────┘
│
▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Response │<────│ Check Scope │<────│ Hash Match │
│ 200/403 │ │ & Expiry │ │ & Active │
└──────────────┘ └──────────────┘ └──────────────┘
Rate Limiting
Endpoint Limits
| Endpoint Category | Limit | Window | Burst |
|---|---|---|---|
Authentication (/auth/*) |
5 requests | 1 minute | No |
API Key Management (/api-keys/*) |
10 requests | 1 minute | No |
Report Generation (/reports/*) |
10 requests | 1 minute | No |
| General API | 100 requests | 1 minute | 20 |
Ingest (/ingest) |
1000 requests | 1 minute | 100 |
Rate Limit Headers
HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1712590260
Rate Limit Response
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 60
{
"error": "rate_limited",
"message": "Rate limit exceeded. Try again in 60 seconds.",
"retry_after": 60
}
CORS Configuration
Allowed Origins
# Development
allowed_origins = [
"http://localhost:5173", # Vite dev server
"http://localhost:3000", # Alternative dev port
]
# Production (configure as needed)
allowed_origins = [
"https://app.mockupaws.com",
"https://api.mockupaws.com",
]
CORS Policy
| Setting | Value | Description |
|---|---|---|
allow_credentials |
true |
Allow cookies/auth headers |
allow_methods |
["GET", "POST", "PUT", "DELETE"] |
HTTP methods |
allow_headers |
["*"] |
All headers allowed |
max_age |
600 |
Preflight cache (10 min) |
Security Headers
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Content-Security-Policy: default-src 'self'
Input Validation
SQL Injection Prevention
- ✅ Parameterized Queries: SQLAlchemy ORM with bound parameters
- ✅ No Raw SQL: All queries through ORM
- ✅ Input Sanitization: Pydantic validation before DB operations
# ✅ SAFE - Uses parameterized queries
result = await db.execute(
select(Scenario).where(Scenario.id == scenario_id)
)
# ❌ NEVER DO THIS - Vulnerable to SQL injection
query = f"SELECT * FROM scenarios WHERE id = '{scenario_id}'"
XSS Prevention
- ✅ Output Encoding: All user data HTML-escaped in responses
- ✅ Content-Type Headers: Proper headers prevent MIME sniffing
- ✅ CSP Headers: Content Security Policy restricts script sources
PII Detection
Built-in PII detection in log ingestion:
pii_patterns = {
'email': r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b',
'ssn': r'\b\d{3}-\d{2}-\d{4}\b',
'credit_card': r'\b(?:\d[ -]*?){13,16}\b',
'phone': r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b'
}
Data Protection
Data Classification
| Data Type | Classification | Storage | Encryption |
|---|---|---|---|
| Passwords | Critical | bcrypt hash | N/A (one-way) |
| API Keys | Critical | SHA-256 hash | N/A (one-way) |
| JWT Secrets | Critical | Environment | At rest |
| User Emails | Sensitive | Database | TLS transit |
| Scenario Data | Internal | Database | TLS transit |
| Logs | Internal | Database | TLS transit |
Encryption in Transit
- TLS 1.3 required for all communications
- HSTS enabled with 1-year max-age
- Certificate pinning recommended for mobile clients
Encryption at Rest
- Database-level encryption (PostgreSQL TDE)
- Encrypted backups
- Encrypted environment files
Security Best Practices
For Administrators
-
Environment Setup:
# Generate strong secrets export JWT_SECRET_KEY=$(openssl rand -hex 32) export POSTGRES_PASSWORD=$(openssl rand -base64 32) -
HTTPS Enforcement:
- Never run production without HTTPS
- Use Let's Encrypt or commercial certificates
- Redirect HTTP to HTTPS
-
Secret Rotation:
- Rotate JWT secrets every 90 days
- Rotate database credentials every 180 days
- Revoke and regenerate API keys annually
-
Monitoring:
- Log all authentication failures
- Monitor rate limit violations
- Alert on suspicious patterns
For Developers
-
Never Log Secrets:
# ❌ NEVER DO THIS logger.info(f"User login with password: {password}") # ✅ CORRECT logger.info(f"User login attempt: {user_email}") -
Validate All Input:
- Use Pydantic models for request validation
- Sanitize user input before display
- Validate file uploads (type, size)
-
Secure Dependencies:
# Regularly audit dependencies pip-audit safety check
For Users
-
Password Guidelines:
- Use unique passwords per service
- Enable 2FA when available
- Never share API keys
-
API Key Management:
- Store keys in environment variables
- Never commit keys to version control
- Rotate keys periodically
Incident Response
Security Incident Levels
| Level | Description | Response Time | Actions |
|---|---|---|---|
| P1 | Data breach, unauthorized access | Immediate | Incident team, legal review |
| P2 | Potential vulnerability | 24 hours | Security team assessment |
| P3 | Policy violation | 72 hours | Review and remediation |
Response Procedures
1. Detection
Monitor for:
- Multiple failed authentication attempts
- Unusual API usage patterns
- Rate limit violations
- Error spikes
2. Containment
# Revoke compromised API keys
# Rotate JWT secrets
# Block suspicious IP addresses
# Enable additional logging
3. Investigation
# Review access logs
grep "suspicious-ip" /var/log/mockupaws/access.log
# Check authentication failures
grep "401\|403" /var/log/mockupaws/auth.log
4. Recovery
- Rotate all exposed secrets
- Force password resets for affected users
- Revoke and reissue API keys
- Deploy security patches
5. Post-Incident
- Document lessons learned
- Update security procedures
- Conduct security training
- Review and improve monitoring
Contact
For security issues, contact:
- Security Team: security@mockupaws.com
- Emergency: +1-XXX-XXX-XXXX (24/7)
Security Checklist
See SECURITY-CHECKLIST.md for pre-deployment verification.
This document is maintained by the @spec-architect team.
Last updated: 2026-04-07