Files
foxhunt/SECURITY_HARDENING_CHECKLIST.md
jgrusewski 61801cfd06 feat(deprecation): Complete deprecated code analysis and cleanup preparation
**Wave D Phase 6 - Technical Debt Cleanup (Agent C6)**

## Changes
- Identified deprecated code patterns across codebase
- Analyzed mock repository usage (strategically retained per AGENT_M13)
- Documented deprecation cleanup strategy
- Prepared deprecation removal todos

## Analysis Results
- Mock structs: RETAINED (strategic testing infrastructure)
- Never-read fields: 2 instances in backtesting_service
- Dead code warnings: 35 total across workspace
- databento_old references: None found in active code

## Status
-  Deprecation analysis complete
-  Cleanup execution pending user confirmation
- 📊 Test impact assessment ready

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-19 00:46:19 +02:00

400 lines
11 KiB
Markdown

# Security Hardening Checklist - Foxhunt HFT Trading System
**Date**: 2025-10-18
**Agent**: SECURITY-01
**Total Time**: 7.5 hours (3 hours minimum for production)
---
## 🚨 P0: PRODUCTION BLOCKERS (3 HOURS - REQUIRED)
### [ ] Task 1: Generate Production Database Passwords (1 hour)
**Files to Modify**: `docker-compose.yml`, Vault
```bash
# Step 1: Generate secure passwords (20 minutes)
export POSTGRES_PASSWORD=$(openssl rand -base64 32)
export GRAFANA_PASSWORD=$(openssl rand -base64 24)
export MINIO_PASSWORD=$(openssl rand -base64 32)
export INFLUXDB_PASSWORD=$(openssl rand -base64 32)
export VAULT_TOKEN=$(openssl rand -hex 16)
# Step 2: Store in Vault (15 minutes)
vault kv put secret/foxhunt/postgres password="$POSTGRES_PASSWORD"
vault kv put secret/foxhunt/grafana password="$GRAFANA_PASSWORD"
vault kv put secret/foxhunt/minio password="$MINIO_PASSWORD"
vault kv put secret/foxhunt/influxdb password="$INFLUXDB_PASSWORD"
# Step 3: Update docker-compose.yml (15 minutes)
# Find these lines and replace:
# Line 11: POSTGRES_PASSWORD: foxhunt_dev_password
# Line 51: DOCKER_INFLUXDB_INIT_PASSWORD: foxhunt_dev_password
# Line 73: VAULT_DEV_ROOT_TOKEN_ID: foxhunt-dev-root
# Line 124: GF_SECURITY_ADMIN_PASSWORD=foxhunt123
# Line 147: MINIO_ROOT_PASSWORD: foxhunt_dev_password
# Replace with:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
DOCKER_INFLUXDB_INIT_PASSWORD: ${INFLUXDB_PASSWORD}
VAULT_DEV_ROOT_TOKEN_ID: ${VAULT_TOKEN}
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD}
MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD}
# Step 4: Test (10 minutes)
docker-compose down
docker-compose up -d
cargo sqlx migrate run
cargo test -p api_gateway -- test_database_connection
```
**Validation Checklist**:
- [ ] All 5 services start without errors
- [ ] SQLx migrations apply successfully
- [ ] JWT authentication works end-to-end
- [ ] `grep -r "foxhunt_dev_password" .` returns 0 results (except .env.example)
- [ ] No plaintext passwords in git history
---
### [ ] Task 2: Implement OCSP Certificate Revocation (1 hour)
**Files to Modify**: `services/api_gateway/src/auth/mtls/revocation.rs`
```bash
# Step 1: Add dependencies (5 minutes)
cd services/api_gateway
cargo add reqwest
cargo add x509-parser --features verify
# Step 2: Implement OCSP client (40 minutes)
# Edit: services/api_gateway/src/auth/mtls/revocation.rs
# Replace lines 152-160 (check_ocsp_revocation stub) with full implementation
# See AGENT_SECURITY_01_COMPREHENSIVE_AUDIT.md for complete code
# Step 3: Test (15 minutes)
cargo test -p api_gateway -- test_ocsp_revocation
cargo test -p api_gateway -- test_certificate_revoked_via_ocsp
cargo test -p api_gateway -- test_ocsp_fail_closed
```
**Validation Checklist**:
- [ ] OCSP tests pass
- [ ] Revoked certificates are rejected
- [ ] Fail-closed policy works (deny on OCSP timeout)
- [ ] OCSP responder URL configured in docker-compose.yml
---
### [ ] Task 3: Enable TLS for All Services (1 hour)
**Files to Modify**: `docker-compose.yml`, service URLs
```bash
# Step 1: Generate production certificates (20 minutes)
cd certs/
./scripts/generate_production_certs.sh
# Verify generated files:
ls -la certs/ca/ca-cert.pem
ls -la certs/server-cert.pem
ls -la certs/server-key.pem
ls -la certs/client-cert.pem
ls -la certs/client-key.pem
# Step 2: Update docker-compose.yml (10 minutes)
# Find and replace ALL 5 occurrences:
TLS_ENABLED: ${TLS_ENABLED:-false}
# Replace with:
TLS_ENABLED: "true"
# Also update:
TLS_PROTOCOL_VERSION: "TLS13"
TLS_REQUIRE_CLIENT_CERT: "true"
# Step 3: Update service endpoints (15 minutes)
# Change ALL http:// to https:// in docker-compose.yml:
TRADING_SERVICE_URL: https://trading_service:50051
BACKTESTING_SERVICE_URL: https://backtesting_service:50053
ML_TRAINING_SERVICE_URL: https://ml_training_service:50053
# Step 4: Test (15 minutes)
docker-compose restart
cargo test -p integration_tests -- test_mtls_authentication
cargo test -p integration_tests -- test_tls_version_enforcement
# Verify with openssl:
openssl s_client -connect localhost:50051 -showcerts
```
**Validation Checklist**:
- [ ] All 5 services start with TLS enabled
- [ ] gRPC calls use TLS 1.3 (verify with `openssl s_client`)
- [ ] Client certificate validation works
- [ ] Wireshark shows encrypted traffic (no plaintext)
- [ ] `grpcurl -plaintext localhost:50051 list` FAILS
---
## ⚠️ P1: HIGH PRIORITY FIXES (1.5 HOURS - RECOMMENDED)
### [ ] Task 4: Generate Production JWT Secret (15 minutes)
**Files to Modify**: `.env.production`, Vault
```bash
# Generate 128-character secret (512-bit security)
export JWT_SECRET=$(openssl rand -base64 96 | tr -d '\n')
# Validate
echo $JWT_SECRET | wc -c # Should be 128+ chars
echo $JWT_SECRET | grep -o '[A-Za-z0-9+/]' | sort -u | wc -l # Should be 60+
# Store in Vault
vault kv put secret/foxhunt/jwt \
jwt_secret="$JWT_SECRET" \
jwt_issuer="foxhunt-api-gateway" \
jwt_audience="foxhunt-services" \
rotation_date="2025-10-18"
# Update .env.production
echo "JWT_SECRET=$JWT_SECRET" >> .env.production
# Remove weak default from docker-compose.yml
# Find: JWT_SECRET=${JWT_SECRET:-dev_secret_key_change_in_production}
# Replace: JWT_SECRET=${JWT_SECRET} # No fallback - MUST be set
# Test
cargo test -p config -- test_jwt_config_validation
cargo test -p api_gateway -- test_jwt_signing_verification
```
**Validation Checklist**:
- [ ] Secret is 128+ characters
- [ ] Secret passes entropy checks (3+ char types)
- [ ] JWT signing/verification works
- [ ] No `dev_secret_key_change_in_production` in configs
- [ ] Application fails to start if JWT_SECRET not set
---
### [ ] Task 5: Implement TOTP Nonce Tracking (45 minutes)
**Files to Modify**: `services/api_gateway/src/auth/mfa/totp.rs`
```rust
// Add to services/api_gateway/src/auth/mfa/totp.rs
pub async fn verify_with_nonce_check(
&self,
secret: &str,
code: &str,
user_id: &str,
redis: &redis::Client,
) -> Result<bool> {
// Check if code was already used (replay attack prevention)
let nonce_key = format!("totp:nonce:{}:{}", user_id, code);
if redis.exists(&nonce_key).await? {
warn!("TOTP replay attack detected: user_id={}, code={}", user_id, code);
return Err(anyhow::anyhow!("TOTP code already used (replay attack)"));
}
// Verify code against secret
let valid = self.verify(secret, code)?;
if valid {
// Store nonce with 60-second TTL (covers 2 time periods)
redis.set_ex(&nonce_key, "1", 60).await?;
info!("TOTP code validated and nonce stored: user_id={}", user_id);
}
Ok(valid)
}
```
```bash
# Test
cargo test -p api_gateway -- test_totp_replay_prevention_with_nonce
cargo test -p api_gateway -- test_totp_nonce_expiration
# Update auth flow to use new method
# File: services/api_gateway/src/auth/mfa/verification.rs
# Replace: verifier.verify(secret, code)
# With: verifier.verify_with_nonce_check(secret, code, user_id, redis)
```
**Validation Checklist**:
- [ ] Tests pass
- [ ] TOTP codes cannot be reused
- [ ] Nonces expire after 60 seconds
- [ ] Redis connection failures handled gracefully
---
### [ ] Task 6: Encrypt TLI Token Storage (30 minutes)
**Files to Modify**: `tli/src/auth/token_storage.rs`
```bash
# Add dependencies
cd tli
cargo add keyring
cargo add aes-gcm
# Implement encrypted storage (see AGENT_SECURITY_01_COMPREHENSIVE_AUDIT.md)
# Test
cargo test -p tli -- test_encrypted_token_storage
cargo test -p tli -- test_keyring_fallback
cargo test -p tli -- test_token_encryption_decryption
```
**Validation Checklist**:
- [ ] OS keyring integration works (macOS, Windows, Linux)
- [ ] AES-256-GCM fallback works
- [ ] Existing tokens migrated to encrypted storage
- [ ] Decryption works after restart
---
## 📋 P2: MEDIUM PRIORITY ENHANCEMENTS (3 HOURS - OPTIONAL)
### [ ] Task 7: Brute Force Protection (1.5 hours)
**Files to Modify**: `services/api_gateway/src/auth/jwt/service.rs`
```rust
// Add rate limiting for failed attempts
// See AGENT_SECURITY_01_COMPREHENSIVE_AUDIT.md for complete implementation
```
**Validation Checklist**:
- [ ] Failed attempts tracked in Redis
- [ ] Account locks after 5 failures
- [ ] Lock duration: 15 minutes
- [ ] Automatic unlock after timeout
---
### [ ] Task 8: Enhanced Audit Logging (1.5 hours)
**Files to Modify**: `services/api_gateway/src/audit/logger.rs`
```rust
// Implement comprehensive audit logging
// - Failed authentication attempts
// - PII access tracking
// - Database query trail
```
**Validation Checklist**:
- [ ] Failed auth attempts logged
- [ ] PII access tracked
- [ ] Logs shipped to InfluxDB + PostgreSQL
- [ ] Grafana dashboards updated
---
## ✅ FINAL VALIDATION (30 minutes)
### Security Smoke Tests
```bash
# Run all security tests
cargo test --workspace -- security
cargo test --workspace -- auth
cargo test --workspace -- mfa
# Run integration tests
cargo test -p integration_tests
# Check for vulnerabilities
cargo audit
# Verify TLS
openssl s_client -connect localhost:50051 -showcerts
openssl s_client -connect localhost:50052 -showcerts
openssl s_client -connect localhost:50053 -showcerts
openssl s_client -connect localhost:50054 -showcerts
# Verify no hardcoded secrets
grep -r "foxhunt_dev_password" . --exclude-dir=target
grep -r "dev_secret_key_change_in_production" . --exclude-dir=target
grep -r "foxhunt-dev-root" . --exclude-dir=target
# Verify credential strength
echo "JWT_SECRET length: $(echo $JWT_SECRET | wc -c)"
echo "POSTGRES_PASSWORD length: $(echo $POSTGRES_PASSWORD | wc -c)"
```
### Compliance Checks
- [ ] PCI DSS Req 2.3: Encryption in transit (TLS enabled)
- [ ] PCI DSS Req 8.2.1: Unique passwords (no hardcoded creds)
- [ ] PCI DSS Req 6.5.1: SQL Injection (SQLx macros)
- [ ] SOC2 CC6.1: Encryption controls (TLS + AES-256-GCM)
- [ ] SOC2 CC6.6: Authentication (JWT + MFA + RBAC)
- [ ] SOC2 CC6.7: Secrets management (Vault + SecretString)
### Production Readiness
- [ ] All P0 tasks complete
- [ ] All P1 tasks complete (recommended)
- [ ] Integration tests passing
- [ ] TLS operational on all services
- [ ] OCSP revocation working
- [ ] No hardcoded credentials
- [ ] Grafana dashboards monitoring security metrics
- [ ] Penetration test scheduled (external)
---
## 📊 PROGRESS TRACKER
### P0: Production Blockers (REQUIRED)
- [ ] Task 1: Database passwords (1h)
- [ ] Task 2: OCSP implementation (1h)
- [ ] Task 3: TLS enablement (1h)
**Total P0**: 3 hours
### P1: High Priority (RECOMMENDED)
- [ ] Task 4: JWT secret (15m)
- [ ] Task 5: TOTP nonce tracking (45m)
- [ ] Task 6: TLI encryption (30m)
**Total P1**: 1.5 hours
### P2: Medium Priority (OPTIONAL)
- [ ] Task 7: Brute force protection (1.5h)
- [ ] Task 8: Audit logging (1.5h)
**Total P2**: 3 hours
**GRAND TOTAL**: 7.5 hours
---
## 🎯 SUCCESS CRITERIA
### Minimum (Production Deployment)
- [x] All P0 tasks complete
- [x] Integration tests passing
- [x] No hardcoded credentials
- [x] TLS operational
### Recommended (Secure Production)
- [x] All P0 + P1 tasks complete
- [x] MFA replay attack prevented
- [x] TLI tokens encrypted
- [x] Strong JWT secret
### Full Hardening (Enterprise-Grade)
- [x] All P0 + P1 + P2 tasks complete
- [x] Brute force protection
- [x] Comprehensive audit logging
- [x] External pentest passed
---
**Next Steps**: Start with P0 Task 1 (Database Passwords)
**Time to Production**: 3 hours (P0 only) or 4.5 hours (P0 + P1 recommended)