Skip to content

Security

Maxime Grenu edited this page Feb 18, 2026 · 1 revision

Security

Summary

ELVIS implements multiple layers of security to protect API credentials and prevent runaway trading losses. All secret handling goes through HashiCorp Vault; no plaintext secrets are ever committed to the repository.


Secret Management — HashiCorp Vault

All API keys, database passwords, and sensitive configuration are stored in HashiCorp Vault.

Setup

# Start Vault (dev mode for local development)
vault server -dev &

# Or use the production config (launchd on macOS)
~/.vault-server/unseal.sh

# Set environment
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN=$(security find-generic-password -a "vault" -s "vault-root-token" -w)

Storing Secrets

# Store Binance API credentials
vault kv put secrets/binance \
  api_key="your_api_key" \
  secret="your_api_secret"

# Store Telegram bot token
vault kv put secrets/telegram \
  bot_token="your_bot_token" \
  chat_id="your_chat_id"

Retrieving Secrets in Code

import hvac

client = hvac.Client(url='http://127.0.0.1:8200', token=os.environ['VAULT_TOKEN'])
binance_creds = client.secrets.kv.v2.read_secret_version(path='binance')['data']['data']
api_key = binance_creds['api_key']

Rules

  • Never put API keys in .env, config.yaml, or any committed file
  • ✅ Use Vault for all secrets, even in development
  • ✅ Rotate API keys regularly
  • ✅ Use read-only API keys (no withdrawal permissions) for trading bots

Kill-Switch

The kill-switch is a hard safety mechanism that halts all trading and (in paper mode) closes all simulated positions when a loss threshold is breached.

How It Works

  1. The RiskManager monitors the current drawdown continuously
  2. When drawdown exceeds max_drawdown_pct (default: 5%), the kill-switch fires
  3. All open positions are immediately closed (in paper mode, marked as closed)
  4. Trading is halted for the remainder of the session
  5. A Telegram alert is sent with the P&L summary and breach details

Configuration

risk:
  max_drawdown_pct: 0.05    # Trigger at 5% drawdown from session high
  kill_switch_enabled: true
  kill_switch_notify: true  # Send Telegram alert on trigger

Manual Trigger

# Emergency stop from CLI
python main.py --kill-switch

# Or send Telegram command (if Telegram bot is enabled)
/stop

Hardening Summary

Control Status Notes
Secrets in Vault All API keys via HashiCorp Vault
No secrets in repo .env and config files in .gitignore
Read-only API keys ✅ Recommended Binance testnet keys used
Kill-switch Triggers on 5% drawdown
Telegram alerts Kill-switch, trade entries, daily summary
Paper trading only No live funds at risk
Audit logging 🔄 Sprint 5 Full decision log planned
Key rotation 📋 Manual Automate in Sprint 5
HSM integration 📋 Sprint 5 Hardware key storage planned

.gitignore Rules

The following are always excluded from the repository:

.env
*.key
*.pem
config/secrets.yaml
logs/
models/*.pkl
models/*.h5
__pycache__/

Reporting a Security Issue

Do not open a public GitHub issue for security vulnerabilities. Contact the maintainer directly via GitHub private message or email.

Clone this wiki locally