# TradeFinder Security Guidelines ## API Key Management ### Key Permissions **Binance Futures API Keys**: | Permission | Required | Notes | |------------|----------|-------| | Enable Futures | Yes | Required for USDⓈ-M trading | | Enable Reading | Yes | Account info, positions, orders | | Enable Spot & Margin Trading | No | Not needed for futures | | Enable Withdrawals | **NEVER** | Do not enable under any circumstances | | Enable Internal Transfer | No | Not needed | ### Key Separation Maintain separate API keys for: 1. **Testnet** (paper trading): Lower security concern, can be more permissive 2. **Production** (live trading): Maximum security, IP whitelist required ```bash # .env structure BINANCE_TESTNET_API_KEY=xxx # Testnet keys BINANCE_TESTNET_SECRET=xxx BINANCE_API_KEY=xxx # Production keys (empty until ready) BINANCE_SECRET=xxx ``` ### IP Whitelisting For production keys: 1. Enable IP restriction in Binance API settings 2. Whitelist only the server IP running the bot 3. If using Docker, whitelist the host machine's public IP --- ## Secrets Storage ### Environment Variables (Required) All secrets must be stored in environment variables: ```bash # Local development cp .env.example .env chmod 600 .env # Restrict file permissions # Docker deployment docker run --env-file .env tradefinder ``` ### What NOT to Do | Violation | Risk | |-----------|------| | Commit `.env` to git | Keys exposed in repo history forever | | Hardcode keys in source | Keys exposed to anyone with code access | | Log API keys | Keys visible in log files | | Share testnet keys | Still bad practice, builds bad habits | ### .gitignore Ensure these patterns are in `.gitignore`: ```gitignore .env .env.* !.env.example *.pem *.key secrets/ ``` --- ## Logging Security ### Sensitive Data Handling ```python # BAD - Never log secrets logger.info(f"API Key: {api_key}") # GOOD - Mask sensitive data logger.info(f"API Key: {api_key[:4]}...{api_key[-4:]}") # BEST - Don't log at all logger.info("API credentials loaded successfully") ``` ### Structlog Configuration ```python # Filter sensitive fields from logs def mask_sensitive(_, __, event_dict): sensitive_keys = ['api_key', 'secret', 'password', 'token'] for key in sensitive_keys: if key in event_dict: event_dict[key] = "***MASKED***" return event_dict ``` --- ## Network Security ### API Endpoints | Environment | Base URL | Notes | |-------------|----------|-------| | Testnet | `https://testnet.binancefuture.com` | Safe for testing | | Production | `https://fapi.binance.com` | Real money | ### Request Signing All authenticated requests must be signed: ```python import hmac import hashlib def sign_request(params: dict, secret: str) -> str: query_string = urlencode(params) signature = hmac.new( secret.encode('utf-8'), query_string.encode('utf-8'), hashlib.sha256 ).hexdigest() return signature ``` ### Rate Limiting Respect Binance rate limits to avoid IP bans: | Limit Type | Value | |------------|-------| | Request weight | 2400/minute | | Order rate | 300/minute | | WebSocket connections | 5/second | --- ## Docker Security ### Container Isolation ```yaml # docker-compose.yml security settings services: engine: security_opt: - no-new-privileges:true read_only: true tmpfs: - /tmp user: "1000:1000" # Non-root user ``` ### Secrets in Docker ```yaml # Use Docker secrets (production) secrets: binance_api_key: file: ./secrets/binance_api_key.txt binance_secret: file: ./secrets/binance_secret.txt services: engine: secrets: - binance_api_key - binance_secret ``` --- ## Operational Security ### Pre-Deployment Checklist - [ ] API keys have NO withdrawal permission - [ ] Production keys are IP-whitelisted - [ ] `.env` is not in git history - [ ] Logs do not contain secrets - [ ] Container runs as non-root - [ ] Redis is not exposed to public network - [ ] DuckDB file has restricted permissions ### Monitoring for Compromise Watch for: - Unexpected positions or orders - API calls from unknown IPs (check Binance API logs) - Unusual account balance changes - Failed authentication attempts ### Incident Response If keys are compromised: 1. **Immediately** delete API key in Binance console 2. Check for unauthorized trades/withdrawals 3. Generate new API key with fresh permissions 4. Review how compromise occurred 5. Update security practices --- ## Testing Security ### Testnet Isolation - Always start with testnet credentials - Verify `TRADING_MODE=testnet` before any trade logic - Production code should fail-safe if mode is unclear ```python def validate_mode(config: Config) -> None: if config.trading_mode == TradingMode.LIVE: if not config.binance_api_key: raise ValueError("Production API key required for live trading") if config.binance_testnet_api_key: logger.warning("Testnet keys present in live mode - ignoring") ``` ### Paper Trading For in-house simulation (no API needed): - Use simulated order fills - No actual API calls - Safe for strategy development --- ## Dependency Security ### Regular Updates ```bash # Check for security vulnerabilities pip audit # Update dependencies pip install --upgrade -r requirements.txt ``` ### Pinned Versions Use exact versions in production: ```toml # pyproject.toml dependencies = [ "ccxt>=4.2.0,<5.0.0", # Pin major version "pydantic>=2.5.0,<3.0.0", ] ``` --- ## Summary | Category | Requirement | |----------|-------------| | API Keys | No withdrawal permission, IP whitelisted | | Secrets | Environment variables only, never committed | | Logging | Mask all sensitive data | | Network | HTTPS only, signed requests | | Container | Non-root, read-only where possible | | Monitoring | Watch for unauthorized activity |