Security
The client is a thin consumer of the Stoa Markets API. Every rule the web application enforces applies unchanged: business verification, second factor, roles and permissions, and the binding acknowledgement before a request is sent. This page describes what the client adds on top.
Credentials
- Session tokens live in the operating system keychain (macOS Keychain, Windows Credential Manager, Secret Service on Linux) under the service name
stoa-cli. There is no plain-text fallback: without a keychain backend the client refuses to store a session. Only those keychain backends (plus libsecret and KWallet) are accepted; any other keyring backend is refused by name. - Tokens never appear in command output, in log lines, in
--debugoutput, in environment variables or in the process arguments. - Your password is read by a hidden prompt and never stored. The second factor is a one-time code.
- There are no long-lived API keys. A session ends after 60 idle minutes and at the daily close, 23:00 UTC.
Scoped sessions
Every command needs a signed-in session, the catalog and the request schema included; the venue serves the client nothing anonymously. A session opened by stoa login is scoped on the server to the operations the client offers: reading the catalog, composing and reading requests, and managing the session itself. Any other call made with that session, including accepting a quote, cancelling a request, submitting a quote, or touching settlement, is refused with a 403 by the venue. A token copied out of the keychain therefore cannot trade. Browser sessions are unaffected and keep their full permissions.
Transport
- The client talks only to
markets.stoaexchange.comover HTTPS. The address is pinned in the client;--base-urlis accepted only for a loopback address in local development. - Redirects are never followed. A redirect, an edge challenge or an HTML page where JSON was expected is reported as an edge problem (exit code 4) and the request stops.
- Cookies set by any response are discarded. The client authenticates with a bearer token only.
Writes
- Every create carries an idempotency key, sent in the body and as the request id. Re-sending with the same key returns the existing request; the venue never opens a second one.
- A create is sent at most twice, both times with the same idempotency key, so a retry can never open a second request. When no response arrives, the message tells you to re-run with the same key.
- A create on the production venue prints the full composition and the binding statement, and asks a person to type the confirmation.
--agree-binding-statementexists for a person who has already read a dry run; the statement is still printed. - Session renewal is single-use. If a renewal is ever replayed, the venue revokes every session for the account, browser included, and you sign in again.
Distribution
The package is published to PyPI as stoa-cli. Install only from PyPI: uv tool install stoa-cli or pipx install stoa-cli.
Reporting a problem
Email [email protected] with a description, the affected command or endpoint, steps to reproduce, and any proof of concept. The vulnerability disclosure page states the ground rules and what to expect; the machine-readable version is at /.well-known/security.txt.