security
exchanges
api-keys
encryption
fund-operations

Onboarding Exchanges Without Leaking Keys: Encrypted Secrets and Live Balances

Jonny Bravo
  -  

...

Onboarding Exchanges Without Leaking Keys: Encrypted Secrets and Live Balances

To run a fund on a platform, you have to do something that should make you nervous: hand it the API keys to your exchange accounts. Those keys can place orders, move positions, and in some configurations withdraw funds. They are, quite literally, the keys to the money. Store them carelessly — plaintext in a database column, logged in an error trace, cached on disk — and a single breach doesn't compromise one account, it compromises every account on the platform at once.

This is the part of "connect your exchange" that the onboarding wizard doesn't show you, and it's the part that should decide whether you trust a platform with real capital. We designed the account layer so that secrets are encrypted everywhere they rest and decrypted only at the instant they're needed to talk to an exchange.

Encrypted at rest, by default

Every sensitive credential is stored encrypted. When the platform needs to actually construct a broker connection to talk to an exchange, it decrypts the secrets in memory, at that moment, and only then:

from development.fund.services.encryption import decrypt_secret def create_broker_instance(account): api_key = decrypt_secret(account['api_key']) if account.get('api_key') else None api_secret = decrypt_secret(account['api_secret']) if account.get('api_secret') else None api_password = decrypt_secret(account['api_password']) if account.get('api_password') else None ... wallet_address = decrypt_secret(account['wallet_address']) if account.get('wallet_address') else None private_key = decrypt_secret(account['private_key']) if account.get('private_key') else None return SomeBroker(api_key=api_key, ...)

Read what's not happening here. The decrypted key never gets written back to the database. It isn't stashed on a long-lived object. It's materialized inside create_broker_instance, handed straight to the broker that needs it, and that's the whole lifespan. The encrypted form is what lives in the database; the plaintext exists only in the narrow window where an actual exchange call requires it.

And it covers the full range of credential shapes — not just the API-key/secret pair, but exchange passwords (api_password), and the wallet address and private key that DeFi-style venues like Hyperliquid use. Every secret a venue might need is treated as a secret: encrypted at rest, decrypted only at the point of use, never logged.

Connect once, see everything in one place

Encryption is the security half. The operational half is what onboarding buys you: a unified view across every venue you connect. Once an account is linked, the platform syncs its live balances and positions on a schedule and writes them into a consistent shape, so a fund spread across Binance USD-M, Kucoin Futures, and Hyperliquid reads as one portfolio, not three exchange tabs you reconcile by hand.

async def update_account_balances(account): ... async def update_account_positions(account): ... async def update_accounts_balances_and_positions(account_ids=None): ... async def update_accounts_positions_by_portfolio_id(portfolio_id): ... async def snapshot_account_balances(account_ids=None, batch_size=1000): ...

That update_accounts_positions_by_portfolio_id is the one that matters for a fund operator. Accounts link to a portfolio, and the executor pulls live positions per portfolio — so the mandate engine knows exactly what the fund currently holds, across all its venues, before it computes a single order. The NAV machinery reads the same synced balances to strike a value. One connection, and the account becomes part of a coherent, fund-level picture instead of an island.

Why this is a trust decision, not a feature

It's easy to under-rate the security of credential handling because, done right, it's invisible. There's no screen for it. Nobody clicks "encrypt my keys." But it is the single most consequential engineering decision between you and a catastrophe, and it's exactly what a serious operator's due-diligence checklist asks about: Where do my keys live? Who can read them? When are they in plaintext?

The answers here are the ones you want to hear. Keys live encrypted in the database. Nothing reads them except the code that builds an exchange connection. They're plaintext only in memory, only during an exchange call, never on disk, never in a log. That's not a marketing claim — it's the structure of the code, visible in the fact that decrypt_secret is called at connection-build time and the result goes straight to the broker and nowhere else.

Connecting an exchange should feel safe enough to do, and consequential enough to take seriously. The platform earns the first by engineering for the second: encrypted at rest, decrypted only at the moment of execution, unified into one portfolio view you can actually run a fund from.

You hand over the keys once. The platform's job is to make sure that's the last time anyone but the exchange ever sees them.


Connect Binance, Kucoin, and Hyperliquid into one portfolio — keys encrypted at rest, decrypted only to trade. Connect an exchange →

Article Contents

Related Articles

© 2026 Fluxy, Inc. All rights reserved.