Skip to content
Browse the docs

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 --debug output, 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.com over HTTPS. The address is pinned in the client; --base-url is 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-statement exists 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.