**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>
400 lines
11 KiB
Markdown
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)
|