- Add Pydantic settings with trading mode validation (paper/testnet/live) - Implement Binance USDⓈ-M Futures adapter with hedge mode, isolated margin - Add type definitions for orders, positions, and market data - Create documentation (PLAN.md, ARCHITECTURE.md, SECURITY.md) - Add setup.sh with uv/pip auto-detection for consistent dev environments - Configure Docker multi-stage build and docker-compose services - Add pyproject.toml with all dependencies and tool configs
5.8 KiB
5.8 KiB
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:
- Testnet (paper trading): Lower security concern, can be more permissive
- Production (live trading): Maximum security, IP whitelist required
# .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:
- Enable IP restriction in Binance API settings
- Whitelist only the server IP running the bot
- If using Docker, whitelist the host machine's public IP
Secrets Storage
Environment Variables (Required)
All secrets must be stored in environment variables:
# 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:
.env
.env.*
!.env.example
*.pem
*.key
secrets/
Logging Security
Sensitive Data Handling
# 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
# 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:
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
# 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
# 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
.envis 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:
- Immediately delete API key in Binance console
- Check for unauthorized trades/withdrawals
- Generate new API key with fresh permissions
- Review how compromise occurred
- Update security practices
Testing Security
Testnet Isolation
- Always start with testnet credentials
- Verify
TRADING_MODE=testnetbefore any trade logic - Production code should fail-safe if mode is unclear
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
# Check for security vulnerabilities
pip audit
# Update dependencies
pip install --upgrade -r requirements.txt
Pinned Versions
Use exact versions in production:
# 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 |