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 runsopenssl rand -hex 32for you and writes it to your local.envasSECRETS_ENCRYPTION_KEY. - The encryption key is independent of your Discord bot token, so rotating one never invalidates the other.
/secrets-statusshows 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
/pnland/summaryshow 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].