- User credentials (password hashes)
- Delta API keys/secrets (encrypted)
- Trading account balances & positions
- Order history & P&L
- Personal information
- Credential stuffing
- Session hijacking
- API key theft
- Order manipulation
- Privilege escalation
- Data exfiltration
- Algorithm: BCrypt with cost factor 12
- Minimum length: 8 characters
- No password reuse: Not implemented (future)
- Breach checking: Not implemented (future)
- Algorithm: HS256 (256-bit secret minimum)
- Access token: 24 hours, HttpOnly cookie
- Refresh token: 7 days, HttpOnly cookie
- Rotation: Refresh rotates access token
- Revocation: Token blacklist on logout
- Stateless JWT (no server sessions)
- Short access token lifetime
- Refresh token rotation
- Automatic logout on token expiry
- Single role:
ROLE_USER - All users equal permissions
- Resource ownership enforced in service layer
// Every service method verifies ownership
tradingAccountRepository.findByIdAndUserId(accountId, currentUserId)
.orElseThrow(() -> new AccessDeniedException("Not your account"));- Delta API secrets: AES-256-GCM (Spring Boot only)
- Database: Transparent encryption (Cloud SQL)
- Backups: Encrypted
- All HTTP: TLS 1.3 (enforced)
- Database: SSL mode require
- Internal services: mTLS (production)
- Development:
.envfiles (gitignored) - Production: Google Secret Manager / HashiCorp Vault
- Never in code: No hardcoded secrets
- Rotation: Quarterly for API keys
| Endpoint Category | Limit |
|---|---|
| Auth | 10 req/min |
| Trading | 60 req/min |
| Market Data | 120 req/min |
| WebSocket | 1 conn/user |
- All inputs validated via Bean Validation
- Sanitization for XSS prevention
- SQL injection prevented by JPA parameters
- Configurable allowed origins
- Credentials allowed
- No wildcard with credentials
Content-Security-Policy: default-src 'self'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=()
Row-Level Security (RLS) NOT YET IMPLEMENTED - planned for hardening phase.
Current isolation enforced at application layer:
- All repository queries include user_id/trading_account_id filters
- Service layer validates ownership before any operation
- No cross-user data access possible through API
Future RLS implementation:
ALTER TABLE trading_accounts ENABLE ROW LEVEL SECURITY;
CREATE POLICY user_isolation ON trading_accounts
USING (user_id = current_setting('app.current_user_id')::UUID);- Every repository query includes user_id/trading_account_id
- Service layer validates ownership
- No cross-user data access possible
- JWT contains user_id
- All endpoints extract user from token
- No user_id in path parameters (inferred from token)
encrypted_api_key TEXT NOT NULL -- AES-256-GCM
encrypted_api_secret TEXT NOT NULL -- AES-256-GCM- Generate random 96-bit nonce per encryption
- Encrypt with AES-256-GCM (authenticated encryption)
- Store:
nonce + ciphertext + auth_tag(Base64) - Key from Secret Manager (rotated quarterly)
- Spring Boot loads encryption key at startup
- Decrypt only when submitting order to Delta
- Never logged, never returned to frontend
- Frontend sees only:
{ connected: true, environment: "LIVE" }
Python Engine NEVER receives Delta credentials.
- Delta credentials stored exclusively in Spring Boot (encrypted)
- Python Engine receives market data only via public/authorized endpoints
- Python Engine communicates with Spring Boot via internal API (BACKEND_API_KEY)
- Spring Boot is the ONLY component with Delta API access
- Authentication (login, logout, failed attempts)
- Account changes (create, update, delete)
- Delta connection (connect, disconnect, test)
- Trading (order place, cancel, fill, position open/close)
- Risk (validation pass/fail, overrides)
- Admin actions (user disable, kill switch)
{
"timestamp": "2024-01-15T10:30:00Z",
"userId": "uuid",
"action": "ORDER_PLACED",
"resourceType": "ORDER",
"resourceId": "uuid",
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0...",
"success": true,
"details": { "symbol": "BTCUSD.P", "side": "BUY" }
}- Security logs: 7 years
- Trading logs: 7 years (regulatory)
- Debug logs: 30 days
- No localStorage for tokens (HttpOnly cookies only)
- No token exposure to JavaScript
- Automatic refresh via interceptor
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self' wss://api.quantedge.ai;">- React auto-escapes
- No
dangerouslySetInnerHTML - Sanitize any user content
- Database: Private subnet, no public IP
- Backend: Private subnet, load balancer only
- Frontend: CDN + WAF
- Python Engine: Private, internal only
- Pod Security Standards: Restricted
- Network Policies: Deny all, allow specific
- Secrets: External Secrets Operator
- Images: Signed, vulnerability scanned
- Failed auth alerts (>5/min)
- Unusual trading patterns
- API error rate spikes
- Database connection anomalies
- Revoke all user sessions
- Force password reset
- Rotate Delta credentials
- Audit recent activity
- Revoke Delta API key immediately
- Generate new key for user
- Audit orders placed with compromised key
- Notify user
- Contain & assess scope
- Notify affected users (72hrs GDPR)
- Regulatory notification
- Post-incident review
- GDPR: Right to deletion, data portability
- SOC 2: Access controls, audit logs
- Financial: Trade retention 7 years
- PCI DSS: Not applicable (no card data)