v0.4.0-beta · exchange infrastructure to build on

Security

Secure by default where we control the surface, explicit about the parts you must add, and honest about where the project stands.

No external audit yet
Open Exchange is beta. The defaults below are real, but the stack has not had an independent security audit, and we don't recommend holding production funds until it has (and you've reviewed your own deployment).

The security posture

The principle throughout: fail closed. An unconfigured deployment rejects requests rather than accepting them, binds to loopback rather than the world, and refuses rather than assumes.

Authentication

Every API call carries Authorization: Bearer <token>. Who the caller is comes from the token, never from a field in the request body. Three modes, selected with OMS_AUTH_MODE:

ModeWhat it isUse it for
api-keyStatic keys mapped to users and roles. The default. With no keys configured, every request is rejected: an unconfigured OMS is closed, not open.Server-to-server integrations
jwtHS256-signed tokens from your identity provider.Plugging in your own user system
devAccepts everything. You have to opt into it by name.Local development, never production

Browser WebSocket clients pass the token as the second Sec-WebSocket-Protocol offer; tokens in query strings are rejected (they end up in logs). The auth layer is a small SPI, so a custom provider is a single class, not a fork.

js
// Browser WebSocket auth: token as the second subprotocol, never in the URL
new WebSocket('wss://oms.example.com/ws', ['bearer', token])

Hardened edges

  • Money and ids are validated at the door: malformed decimal strings, out-of-range values, and oversized fields get a 400, not a stack trace.
  • CORS is an explicit allowlist; the default allows no browser origins.
  • Secrets can be read from files (*_FILE variants), keeping them out of environment listings.
  • Every authenticated mutation lands in an append-only audit log.
  • Foreign order ids return 404, not 403, so ids can't be probed for existence.
  • CI runs dependency and secret scanning (Trivy, plus govulncheck on the Go code) on every commit, in every repo.

The admin plane

The admin gateway binds to 127.0.0.1 by default and refuses to bind wider unless a bearer token is configured. Process execution is shell-free (no command-string injection surface). Treat :8082 as root on the exchange: if you expose it beyond the box, put your own network controls in front as well.

What you still own

Open Exchange terminates none of your perimeter. TLS, DDoS protection, rate limiting at the edge, IP allowlists, and network segmentation are yours, as are KYC, custody, and licensing (see scope). A reasonable minimum for anything internet-facing: a TLS-terminating reverse proxy in front of the OMS, the admin gateway reachable only over a private network or tunnel, and the cluster ports never exposed at all.

Reporting a vulnerability

Privately, please: email info@openexchange.dev with the repo, impact, and reproduction steps, or use GitHub's private reporting if enabled on the repo. Don't open a public issue. The full policy, including scope and what we prioritize, is in each repo's SECURITY.md.

Open Exchange

The open-source core to launch your own exchange. Fast, fault-tolerant, built in public.

v0.4.0-beta

Apache 2.0 · Beta software: the public API is frozen, but it has not had an external security audit yet and should not hold production money until it does. Open Exchange is the infrastructure you build an exchange on; KYC/AML, custody, fiat, identity, and compliance are the integrator’s responsibility.