Security
The LEXX API is built so that the worst case stays small: no reusable secret ever travels with a request, every key can be fenced by permissions, IP addresses and trading limits, and revocation is instant. This page collects the whole security surface in one place.
The trust model
Authentication is Ed25519 signatures, not API secrets:
- Your private key never leaves your machine — LEXX stores only the public key.
- Every request carries a one-time signature over its exact content (the signing rule); tampering with a single byte invalidates it.
- Replay is blocked twice: a signature is accepted only once, and only within ±5 s of server time (details).
- Even a full compromise of LEXX’s database cannot forge a request on your behalf — there is nothing secret to steal server-side.
What this means practically: the private key file is the only thing you must protect.
Key permission tiers
| Tier | Can |
|---|---|
read |
Read balances, positions, orders, bots; subscribe to WebSocket streams |
trade |
Everything read can + place/cancel orders, manage bots, change leverage/margin, convert dust |
full |
Superset of trade. No public endpoint currently requires more than trade — key management stays in the Terminal UI by design |
Least privilege in practice: monitoring and analytics run on read keys; only the component
that actually trades holds a trade key.
IP whitelist
Each key may carry up to 10 CIDR entries. Requests from any other address are rejected —
REST answers 403 IP_NOT_WHITELISTED, the WebSocket sends IP_REJECTED (same condition,
different name). A stolen key without your egress IP is a paperweight.
Mind the operational details: NAT and cloud egress gateways change your visible IP; when your infrastructure moves, update the whitelist before the traffic moves.
Risk shields — per-key trading limits
Shields cap what a key can do even if fully compromised. Configured per key in the Terminal UI:
| Shield | Status | Effect |
|---|---|---|
allowedExchanges |
ENFORCED | The key may only touch the listed exchange accounts. Checked on orders, leverage/margin changes and bot creation (including the exchange inside bot settings). Violation → 403 EXCHANGE_NOT_ALLOWED |
If a shield check itself fails to evaluate, the API fails closed and blocks the action
(500 RISK_SHIELD_ERROR) — safety wins over availability.
A sensible production setup for a trading bot’s key:
trade tier + IP whitelist + allowedExchanges: ["binance-futures"].
Key lifecycle and monitoring
- Up to 10 active keys per account; registration and revocation only in the Terminal UI (the API deliberately cannot mint or modify keys).
- The Terminal shows per-key metadata: masked
publicKeyPrefix,label,tier,isActive,createdAtandlastUsedAt— review the latter periodically; a key that “shouldn’t be in use” but has a freshlastUsedAtis an incident. - Revocation is instant: REST requests start failing immediately and open WebSocket
sessions are closed with code
4003.
Storage hygiene
- Keep
lexx-api-key.pemout of version control (.gitignore),chmod 600, or better — in a secrets manager (Vault, AWS Secrets Manager, Doppler…). Inject via environment/volume at runtime. - One key per application/bot/environment. Small blast radius, meaningful
lastUsedAt, painless rotation. - Never paste the private key into chats, tickets or logs. LEXX support will never ask for it — there is nothing they could legitimately do with it.
Incident response runbook
Suspect a leak (key in a public repo, strange orders, unexpected lastUsedAt)?
- Revoke the key in the Terminal UI — takes effect immediately (WS closes with
4003). - Audit what happened:
GET /orders?status=recentfor the last hour of orders,GET /orders/tradesper symbol for executions,GET /botsfor bots you didn’t create — plus the account history in the Terminal. - Check the collateral: leverage/margin settings (Portfolio), open positions.
- Re-issue: generate a fresh key pair (Authentication → Creating keys), register it with tight shields, update your deployment, verify, done.
- If anything looks like platform-side abuse, contact
support with the relevant
meta.requestIds.
Platform-side protections (for completeness)
Things LEXX enforces regardless of your configuration: request bodies capped at 100 KB
(413), per-route rate limits plus a pre-auth IP limiter,
WebSocket DoS backstops (frame size, message rate,
connection caps, slow-consumer cutoff), single-use WS auth challenges, and generic 500
messages that never leak internals.
Verified against API spec v2.0.0 · 2026-07-12