Security model
Non-custodial, and read-only for the moment — placing trades will come later.
That rules out losing your funds. It does not rule out losing your data: one file on your machine holds a key to every venue you connect.
Every copy comes from here. tula is built from github.com/hsnice16/tula and published on its install page, Homebrew and npm — the same binary everywhere.
Promises, and what enforces them
- No code path can move funds off a venue
- no endpoint that moves funds, in any connector
- Nothing places an order, for the moment
- the build fails if an order endpoint appears
- A key that can move funds is turned away, not warned about
- checked against the venue at connect time
- Your keys never reach the model
- the agent layer cannot import a connector or the store
- Your keys stay on your machine, in one file
- mode 600, and refused if anything else can reach it
- A price-source key is typed into a prompt
- never on a command line your history would keep
Making a read-only key that passes the check: Kraken, Binance and Coinbase.
Limits
Never a seed phrase
On-chain, a public address is all tula needs. No screen asks for a seed phrase. The only private key it loads is a Coinbase CDP key, used only to read.
Not encrypted at rest
Your keys sit in one plain file only you can read (mode 600). Other users on the machine cannot open it; a backup or software running as you can.
What you type
Lines you send are saved with the same protection, so ↑ reaches past sessions. Keys, seed phrases, connect screens and lines starting with a space are never saved. TULA_NO_HISTORY=1 keeps nothing.
Unknown is a value
Stripe publishes no way to check what a key can do, so tula says unknown rather than safe. A missing price shows as missing, never as zero.
The model never computes
Every number is worked out in code first. The model only reads the results; it cannot reach a venue or your keys.
The install is checked
The installer stops if the checksum does not match. With the GitHub CLI signed in, it also checks who built the binary; without it, it says that was not proven.
Text tula did not write
Some text comes from outside tula: a Hyperliquid builder dex name, a token name as the configured token list names it or as an Aave reserve contract returns it, and errors from a venue or a price source or the model provider. All of it is cut short and cleaned before it reaches the screen or the model.
What tula connects to
The venues you connect, your price source, token lists, and public nodes for Ethereum, Arbitrum One, Base, Polygon, Optimism, Avalanche, Gnosis, Scroll and Linea. If a node is down tula tries the next one, which then also sees your address. Anthropic gets only finished numbers, and only when you ask a question. The shell checks GitHub for a new release each time it opens. The binary tracks nothing; this site uses Google Analytics, asking first in Europe, and shows a Peerlist badge.
Found a hole? Report it privately, never as a public issue. SECURITY.md says how to send it, what counts as in scope, and how long a reply takes.