Guides

Security & Data

What's encrypted, what stays on your instance, and exactly what Ionide-operated services ever see.

Ionide doesn't custody funds and isn't an exchange — your assets stay on the exchange account you connect, and Ionide only ever gets trading-only API access to it. This page covers how your exchange credentials are stored, and precisely what data does or doesn't leave your own self-hosted instance.

How your exchange API keys are stored

  • Keys are encrypted with AES-256-GCM before being written to your instance's local database (a Docker volume, /app/data), using a key you generate yourself — the installer runs openssl rand -hex 32 for you and writes it to your local .env as SECRETS_ENCRYPTION_KEY.
  • The encryption key is independent of your Discord bot token, so rotating one never invalidates the other.
  • /secrets-status shows which exchanges have credentials configured without ever decrypting them. Stored values are never echoed back in Discord, not even to the bot owner.
  • Decryption happens only in-memory, at the moment the bot places or checks on a trade for you — never as part of any request to an Ionide-operated service.

What never leaves your instance

Your raw API key, secret, and (for Bitget) passphrase are never transmitted anywhere once you've entered them via /secrets-set — not to product-api, not to alpha-engine, not in logs. If you lose your SECRETS_ENCRYPTION_KEY, those stored credentials can't be decrypted by anyone, including us — you'd need to run /secrets-set again with a new key.

What does leave your instance

Your license key and a generated instance ID accompany every request below, used to validate entitlement (/v1/licenses/validate) and associate your instance with your license.

  • Command-center rendering: aggregate trading metrics (APR, PnL, max drawdown, and per-symbol funding-profit series) — the same numbers /pnl and /summary show you in Discord — sent so the summary/chart images product-api renders for your command center reflect your actual results.
  • Heartbeat (every 5 minutes, while the bot is running): your currently-open positions (symbol, side, notional size, last-updated time), per-exchange API latency stats, JVM memory/uptime/thread count, and cumulative trade entry/exit counts (successful, failed, simulated). This is what lets us confirm an instance is alive and see current arbitrage state without you having to report it.
  • Exception reports (sent immediately, off the bot's main thread, whenever it hits an unhandled error): the exception's message, its full stack trace, and a short label of where it occurred — so issues can get caught and fixed without you having to report them yourself.

That's the complete list. No exchange credentials, no wallet addresses, and no per-trade order details are included in any of it.

Permission scoping

Ionide only ever requests trading permissions on your exchange API key — never withdrawal access. See Adding Exchange API Keys for exact steps per exchange, and run /secrets-test after setting a key: it checks the key works and, where the exchange's API exposes it, confirms withdrawal permission is actually off. Revoke a key from your exchange's own dashboard at any time — the bot loses trading access immediately but never had a way to move funds out in the first place.

Your own infrastructure

Ionide runs as a container on infrastructure you control — Docker host security (OS updates, SSH access, who can reach your Docker daemon) is your responsibility, the same as any other self-hosted service. See Self-Hosting Ionide for what the installer does and where the encryption key and database live so you can back them up.

Questions?

Reach out on Discord or [email protected].