Your keys cannot
move your money.
That is a structural statement, not a policy one. A key with withdrawal permission is refused at connection time, secrets are decrypted only inside a service with no public route, and every administrative action lands in a log that cannot be edited from inside the product.
- AES-256
- envelope
- TLS 1.3
- in transit
- 0
- withdrawal scopes
- Append
- only audit
Envelope encryption
a7f3·9c21·4e8b·d05a·6f7e·13c9·88b2·e4d1
The secret is decrypted only inside the execution service, in memory, for the duration of a request. It is never written to a log, never returned by an API, and never visible in the product again after it is entered.
Where your keys live
A trading key is the only thing you hand over, so it is worth being exact about what happens to it.
Entered once
The secret is submitted directly to the key service over TLS and encrypted before the response returns. It is never held by the web app, never placed in a session, and never rendered again.
Decrypted in one place
Only the execution service can unwrap a data key, and only in memory for the duration of a request. It has no inbound public route and no interactive shell.
Rotatable without downtime
A replacement key can be attached and the old one revoked while positions are open; in-flight orders continue under the outgoing key until it drains.
Never in a log
Secrets are redacted at the serialiser rather than at each call site, so a new endpoint cannot leak one by omission.
What the key is allowed to do
Encryption protects a secret at rest. Scope protects you from what the secret can do if it ever leaks.
Key scope, enforced at connection
- Read balancesrequired for sizing
- Read positionsrequired for exposure
- Place ordersrequired to trade
- Cancel ordersrequired for management
- Withdraw fundsconnection refused if enabled
- Internal transferconnection refused if enabled
- Sub-account adminnever requested
- Margin borrowoff unless you opt in
A key with withdrawal permission is rejected at the moment you try to connect it, not merely unused. The worst case of a compromise is unwanted trading — not a drained account.
IP allowlisting
Where a venue supports it, the connection is bound to our egress addresses, so a leaked key is unusable from anywhere else.
Separate keys per venue
One key per venue per tenant. Revoking one never interrupts another.
Read-only mode
A connection can be attached in read-only scope to run analysis and paper trading against a real account without any order permission at all.
Zero trust, meaning no implicit trust
Being inside the network is not a credential. Every hop authenticates independently.
Execution enclave
The only service that can decrypt a trading key. No inbound public route, no shell access, no log sink that could receive plaintext.
Each boundary re-authenticates. A caller that has crossed three of them still presents credentials to cross the fourth.
A record nobody can quietly edit
An audit log that can be amended is a formality. This one chains.
Append-only audit log
chain intact| time | actor | action | from | to | prev hash |
|---|---|---|---|---|---|
| 14:02:11 | you@desk | risk.daily_cap | 3.0% | 2.5% | 9c21f0… |
| 13:47:52 | you@desk | key.rotate | binance-01 | binance-02 | 4e8bd0… |
| 11:20:04 | system | trading.halt | running | halted | a7f39c… |
| 09:58:33 | ops@team | strategy.promote | paper | live | 13c988… |
| 09:14:07 | system | order.fill | — | 12.4 SOL | 6f7e13… |
Each entry carries the hash of the one before it, so a deleted or edited row breaks the chain and the break is detectable. Nothing in the product exposes a way to amend an entry — including to us.
What is recorded
Configuration changes, key attach and rotate, strategy promotion, halts, resumes, manual overrides and every order lifecycle event.
What is stored with it
Actor, source address, user agent, the previous value and the new one — enough to answer “who changed this” without a second system.
Where it can go
Exportable on a schedule to your own retention or SIEM, so the record survives independently of us.
Where it runs
Regional isolation, per-tenant separation, and no shared execution state between accounts.
eu-central
Frankfurt
Primary · EU tenants
8 ms to Binance EU
ap-northeast
Tokyo
Primary · APAC tenants
6 ms to Bybit
us-east
Virginia
Primary · Americas
11 ms to OKX US
Tenant isolation
- Per-tenant data keys — decrypting one account's secrets tells you nothing about another's
- Row-level authorisation enforced in the data layer, not in the request handler
- Execution workers are pinned per tenant; no shared order state between accounts
- Backups are encrypted with the same envelope scheme and restored per tenant
Operational posture
- Immutable deploys — no in-place patching, every release is a new image
- Secrets injected at runtime from a managed store; none exist in the repository or the image
- Least-privilege workload identities with short-lived credentials, rotated automatically
- Risk and execution fail closed: if a dependency is unreachable, trading stops rather than continues unchecked
Security is a claim you should be able to check. If something here is not specific enough to verify, that is a defect in the page — tell us and we will make it concrete or remove it.