Commit Graph
75 Commits
Author SHA1 Message Date
zeekay a43e175760 feat: OFAC wallet screening + crypto KYT endpoint
- POST /compliance/wallet-screen: checks addresses against 47 OFAC SDN
  sanctioned wallets (Tornado Cash, Lazarus Group, Garantex, etc.)
- Falls through to Jube for real-time risk scoring
- Self-service accessible (any org)
- 11 new tests covering OFAC hits, case insensitivity, chains, directions
2026-04-03 16:00:04 -07:00
zeekay 8fc466fd0a feat: add Unregister to provider Registry (runtime provider removal) 2026-04-03 15:29:50 -07:00
zeekay d4fb39fa11 add applications table migration (016, 017) 2026-04-03 15:04:45 -07:00
zeekay 2957c9e773 refactor: org-based RBAC, drop isAdmin/roles claims
Org IS the role:
- built-in org = full admin access to all compliance modules
- Any other org = self-service only (sessions, applications, kyc)

Removed: RequirePermission, HasRole, X-User-Roles, X-User-IsAdmin
Added: requireOrgAccess (checks X-Org-Id against adminOrg)
Added: localnet environment config
2026-04-03 14:57:22 -07:00
zeekay b6191d040e fix: built-in org users get X-User-IsAdmin (Casdoor JWT lacks isAdmin claim) 2026-04-03 14:48:47 -07:00
zeekay 872c13d867 split self-service vs admin routes: sessions/applications open, admin behind built-in org 2026-04-03 14:27:39 -07:00
zeekay 454b735593 feat: compliance restricted to built-in org, RequireOrg middleware
- auth.RequireOrg() middleware rejects requests from wrong org
- Compliance routes require built-in org (COMPLIANCE_ADMIN_ORG env var)
- SuperAdmin users (built-in org) manage compliance for all customer orgs
- Customer data lives in liquidity org, admin access via built-in org
- Tests updated to use built-in org
2026-04-03 14:22:51 -07:00
zeekay 1a99305992 allow self-service onboarding for authenticated users without roles 2026-04-03 14:19:44 -07:00
zeekay b219edd2c9 security: fix all critical/high findings from red team review
- Strip 9 identity headers at start of every request (prevents injection via direct pod access)
- Remove X-Account-Id fast path and fallback headers from frontend handlers (fixes IDOR)
- Add gRPC auth interceptor with IAM JWKS validation
- Fix RBAC role splitting (comma-separated X-User-Roles)
- Move webhook endpoint outside auth middleware
- Fatal on empty SSN_HMAC_KEY in production
- Remove dead admin store code
- Remove duplicate CORS handler from compliance router
- Fix writeErr JSON injection (use json.Marshal)
- Propagate isAdmin + roles claims from JWT
2026-04-03 14:13:17 -07:00
zeekay f29020297f feat: add IAM JWKS validation to auth middleware
Middleware now validates Bearer tokens against IAM JWKS endpoint
(IAM_ENDPOINT/.well-known/jwks). Extracts sub, owner, email claims
and sets X-User-Id, X-Org-Id, X-User-Email headers.

Also accepts gateway-propagated headers (X-User-Id) for deployments
behind Hanzo Gateway. One auth path: IAM only.
2026-04-03 13:56:14 -07:00
zeekay 0c02dd3424 fix: compliance auth checks X-User-IsAdmin from IAM JWT (no separate admin store) 2026-04-03 13:53:58 -07:00
zeekay 4df5223100 refactor: remove internal auth, use IAM via gateway only
All authentication now goes through Hanzo Gateway → IAM JWKS.
The broker reads identity from gateway-propagated headers
(X-User-Id, X-Org-Id, X-User-Email, X-User-Roles) and never
validates JWTs or API keys internally.

- Remove auth.Store, auth.APIKey, API key middleware
- Remove admin.Middleware from compliance router
- Remove /auth/login and /auth/verify endpoints
- RBAC reads X-User-Roles header from gateway
- Reviewer identity from X-User-Id header
- /healthz remains unauthenticated
- Rename super_admin → superadmin
2026-04-03 13:40:51 -07:00
zeekay 1d940ce212 chore: symlink AGENTS.md and CLAUDE.md to LLM.md
Canonical project context lives in LLM.md. Symlinks ensure
agentic coding tools (Claude Code, Cursor, etc.) find context
automatically regardless of which filename they look for.
2026-04-01 14:08:13 -07:00
zeekay 5e5edb227a chore: update dependencies 2026-04-01 13:59:38 -07:00
zeekay a710df9da2 ci: use <tenant>/.github shared workflow (GKE runners) 2026-04-01 13:36:46 -07:00
zeekay a644e17f16 ci: native multi-arch Docker builds (amd64 + arm64, no QEMU) 2026-04-01 13:33:29 -07:00
zeekay 49d964fdef fix: require explicit role for trade permission (SEC Rule 301(b)(5))
Default grant for authenticated IAM users now only covers "read" (browsing
market data). Trade permission requires explicit role assignment to prevent
pre-KYC users from placing orders on the ATS.
2026-03-31 20:49:27 -07:00
zeekay 445d25465a fix: accept X-User-Id header and X-Account-Id fast path for per-user account scoping
resolveUserID now checks X-User-Id first (set by ATS injectAuthHeaders)
before falling back to X-Gateway-User-Id and X-Hanzo-User-Id.

resolveUserAccounts short-circuits on X-Account-Id + optional
X-Account-Provider headers, skipping the ListAccounts call when the
caller already knows the sub-account.
2026-03-31 16:16:36 -07:00
zeekay a1ad0aa1b0 fix: compliance init for CI, alpaca crypto snapshot test mock 2026-03-31 12:55:08 -07:00
zeekay 43d96a28e9 fix: bump compliance to v0.2.0, simplify CI 2026-03-30 20:39:35 -07:00
zeekay 596ddcdd1b fix: update compliance module checksum 2026-03-30 20:29:21 -07:00
zeekay 4f436df93a ci: add GitHub Actions — :main/:test/:dev image tags 2026-03-30 20:23:56 -07:00
zeekay 27ad8b7090 security: role-based permissions for IAM users in RequirePermission
IAM-authenticated users no longer get implicit admin access. RequirePermission
now checks X-User-Roles header for the required permission. Default IAM users
without explicit roles get read + trade only. Admin endpoints require explicit
admin role in JWT claims.

Adds hasRole() helper for comma-separated role string parsing.
2026-03-30 20:11:32 -07:00
zeekay 32ee53d6f5 fix: remove hardcoded WL origins — CORS from CORS_ALLOWED_ORIGINS env var 2026-03-30 18:43:13 -07:00
zeekay c01bbb0eab fix(ibkr): global exchange support — TSX, LSE, HKEX via contract search
resolveConid now uses POST /iserver/secdef/search for proper
multi-exchange symbol resolution. Supports TSX symbols (U.UN,
SPUT.TO), LSE (VOD.L), HKEX, etc. SMART routing auto-selects
best execution venue.
2026-03-30 18:28:17 -07:00
zeekay 0bb03de5bf feat: add Apex provider + futures/FX/bonds/margin interfaces
- FuturesProvider, FXProvider, FixedIncomeProvider, MarginProvider interfaces
- Apex Clearing provider (self-clearing, 1-4 leg options, futures, margin)
- 20 new types: FuturesContract, FXPair, Bond, AccountMargin, etc.
- Registered in envconfig (APEX_API_KEY, APEX_API_SECRET, APEX_SANDBOX)
- 17 providers total (Alpaca, Apex, IBKR, Tradier, CurrencyCloud, LMAX, etc.)
2026-03-30 16:11:00 -07:00
zeekay 5de9cbe333 feat: add options trading — Alpaca Level 3 multi-leg support
- OptionsProvider interface (7 methods): chain, expirations, quote,
  single-leg orders, multi-leg orders, exercise, positions
- Alpaca implementation: order_class "mleg", ratio_qty, position_intent
- Fix 3 critical bugs: mleg class, ratio_qty field, position_intent
- Add DoNotExercise + SetOptionsApprovalLevel endpoints
- HTTP handlers: 10 new routes under /v1/options/*
- Security: OCC symbol validation, input sanitization, audit logging
- Tests: 16 provider + handler tests passing
2026-03-30 15:25:47 -07:00
zeekay 760d8e710e fix: default ListOrders to status=all (Alpaca defaults to open only) 2025-12-24 22:00:00 -07:00
zeekay b9afd116a8 fix: set Account.ID from provider ID in Alpaca toUnified
Account.ID was empty causing SmartOrder to call
/v1/trading/accounts//orders (double slash, 404).
2025-12-24 21:46:11 -07:00
zeekay a798507a84 debug: log alpaca 4xx responses with URL 2025-12-24 21:37:48 -07:00
zeekay dcdde1d895 fix: auto-resolve account in SmartOrder when accounts map is empty
When the caller doesn't provide explicit provider→account mappings,
SmartOrder now auto-discovers the first available account for the
best provider. Fixes "no account configured" errors from ATS.
2025-12-24 21:15:47 -07:00
zeekay 8723d2fc14 feat: add Hyperliquid perpetuals DEX provider
Read-only integration with Hyperliquid API:
- Market data: snapshots, bars, trades, quotes via /info endpoint
- Account state: clearinghouse positions and margin
- Open orders query
- Order execution stubbed (needs wallet signing)
2025-11-15 14:23:41 -08:00
zeekay f1fd941892 fix: clean up dead code in auth middleware, fix RequirePermission bug
- Remove unreachable ATS proxy X-User-Id block (already handled above)
- Fix RequirePermission: was checking X-User-Id twice instead of
  X-User-Id || X-IAM-User-Id
- Change error message to "authentication required" for consistency
2025-12-24 19:09:01 -07:00
zeekay 03c7446a38 revert: restore Dockerfile + cloudbuild — broker is a deployed BD service 2025-12-24 18:45:12 -07:00
zeekay edbf521a7c chore: remove Dockerfile + cloudbuild — Go module, not a standalone service 2025-12-24 18:42:57 -07:00
zeekay 9ece9df4f9 chore: remove Dockerfile + cloudbuild — Go module consumed by ATS, not deployed standalone 2025-12-24 18:42:36 -07:00
zeekay 548f2afc6f fix: update go.sum for compliance v0.1.0 retag 2025-12-24 18:31:19 -07:00
zeekay 0ea4596279 fix: remove replace directive, fix Dockerfile for Cloud Build 2025-12-24 18:08:24 -07:00
zeekay 000872b610 security: SSN key mandatory, CORS env-gated, role mutation locked to super_admin
- SSN_HMAC_KEY: now required unconditionally (init panic) — no fallback
- CORS: localhost origins only allowed when BROKER_ENV != production
- Role mutation (POST/PATCH/DELETE /roles) restricted to super_admin or
  owner via requireSuperAdmin guard — prevents self-escalation (HIGH-3)
- Role list/get now requires roles:read RBAC guard
2025-12-24 17:45:51 -07:00
zeekay 4d2f28a2f7 security: harden compliance router — full RBAC, library delegation, audit logging
- Add RBAC guards to ALL read endpoints (pipelines, sessions, funds,
  esign, templates, dashboard, users, transactions, reports, settings,
  credentials, billing, envelope views) — previously 20+ GET routes
  had no permission checks
- Wire Jube client into amlHandler via RouterOption pattern
- Replace NewRouter variadic authStore param with proper RouterOption API
- Delegate seed roles to rbac.DefaultRoles() — fixes drift where seed
  was missing aml and applications modules
- Delegate modules list to rbac.ComplianceModules() — single source of truth
- Delegate onboarding helpers (newApplicationSteps, isTerminalStatus,
  markStepCompleted, markStepFailed) to compliance library
- SSN HMAC key: hard-fail in production if SSN_HMAC_KEY not set
- Add audit logging when super_admin RBAC bypass is used
- Credential management elevated to roles:admin (was unguarded)
2025-12-24 17:43:04 -07:00
zeekay 9282ad33b0 refactor: compliance imports from lux/compliance library (thin HTTP layer)
Replace local compliance types, store, MemoryStore, and jube package with
imports from github.com/luxfi/compliance. Broker's pkg/compliance/ is now a
thin HTTP adapter layer:

- compliance.go: type aliases re-exporting all types from library
- store.go, jube/: removed (moved to library)
- postgres_store.go: kept (pgx dependency stays in broker)
- All HTTP handlers unchanged (types are aliases, fully compatible)
- Router imports jube from library instead of local subpackage

go.mod adds: require github.com/luxfi/compliance v0.1.0
             replace github.com/luxfi/compliance => ../compliance

All 50+ compliance tests pass. No handler code changes needed.
2025-12-24 17:32:14 -07:00
zeekay 18a7205912 security: fix Red team findings — reviewer spoofing, step ordering, RBAC, rate limiter 2025-12-24 17:09:25 -07:00
zeekay c41b1ed2fe security: harden compliance API — SSN HMAC, doc validation, error sanitization, rate limits
- SSN hashing: upgrade from plain SHA-256 to HMAC-SHA256 with keyed secret
  (SSN_HMAC_KEY env var from KMS) to prevent rainbow table attacks on the
  small 10^9 SSN keyspace
- Document uploads: validate MIME type (pdf/jpeg/png/tiff only), enforce
  10MB size limit, validate base64 encoding
- Error messages: sanitize all handler error responses to prevent leaking
  internal store errors (PostgreSQL query details, path info) to clients
- Rate limiting: add per-IP rate limits (10/min) on KYC verify, AML screen,
  and AML risk-assessment endpoints
- Security headers: add X-Content-Type-Options, X-Frame-Options, Cache-Control
  to all compliance responses
2025-12-23 16:45:29 -07:00
zeekay cc173c8f9f feat: add KYC/AML and onboarding endpoints to compliance module
Add full compliance onboarding flow supporting the 5-step application:
1. Basic info + contact (SSN hashed with SHA-256, never stored plaintext)
2. Identity verification (pluggable KYC provider)
3. Document upload with metadata tracking
4. AML/compliance screening (Jube sidecar integration)
5. Review + submit with admin approval/rejection

New endpoints:
- /aml/screen, /aml/risk-assessment, /aml/flagged, /aml/screenings/{id}/review
- /applications/ CRUD + /step/1-5 + /review + /documents
- /kyc/ list by user, PATCH status, POST documents

Includes MemoryStore + PostgresStore implementations, migration SQL,
107 passing tests (51 new).
2025-12-23 16:06:32 -07:00
zeekay 3c79a26fd0 fix: convert Bar timestamps to epoch ms (TimeMs field) for frontend charts 2025-12-23 15:20:26 -07:00
zeekay d72af7a15f fix: accept X-IAM-User-Id fallback during gateway transition 2025-12-23 12:05:50 -07:00
zeekay c966ac7e1d fix: unified auth — X-User-Id + X-Org-Id, no prefixes
Auth middleware now accepts:
1. X-User-Id + X-Org-Id headers (set by Gateway after JWT validation)
2. API key (Authorization: Bearer or X-API-Key) for service-to-service

No X-IAM-, X-Broker-, or other prefixed headers. One way to auth.
2025-12-22 23:00:33 -07:00
zeekay 0ede160d2e fix: bypass API key auth for ATS proxy requests
When X-Broker-User-Id header is present, the request comes from the
ATS proxy which already validated the user's JWT via Gateway. Skip
API key check and pass through to allow trading endpoints to work
for authenticated users.
2025-12-22 22:51:54 -07:00
zeekay 4532862f22 fix: use query-param format for crypto bars (sandbox single path 404s)
Same issue as snapshots — Alpaca sandbox returns 404 for
/v1beta3/crypto/us/{sym}/bars but works with
/v1beta3/crypto/us/bars?symbols={sym}. Also handle the wrapped
response format {"bars":{"BTC/USD":[...]}} vs stock {"bars":[...]}.
2025-12-24 00:57:08 -07:00
zeekay 2b8c5625b7 fix: use batch snapshots endpoint for crypto (sandbox single endpoint 404s)
Alpaca sandbox's single crypto snapshot endpoint (/v1beta3/crypto/us/{sym}/snapshot)
returns 404. Use the batch endpoint (/v1beta3/crypto/us/snapshots?symbols={sym})
which works on both sandbox and production.
2025-12-23 23:13:27 -07:00
zeekay c3a7a1172b test: boost coverage — accounts resolver, frontend API, funding (+820 lines) 2025-12-20 12:46:39 -07:00
zeekay 444985a91d chore: update LLM.md, go.mod after envconfig refactor 2025-12-20 12:39:12 -07:00
zeekay 13c2e1f23b feat: extract RegisterFromEnv to pkg/provider/envconfig for reuse
Move all 16 provider env-var registration into a reusable function.
Any ATS/BD/TA calls envconfig.RegisterFromEnv(registry) instead of
duplicating 130 lines of if-blocks. brokerd/main.go drops from 264
to 88 lines. Tests included.
2025-12-20 12:23:14 -07:00
zeekay 664e1496aa security: fix all critical findings from red team review
- JWT signature comparison now uses hmac.Equal (timing-safe)
- Password hashing upgraded to 100k iterations (PBKDF2-like)
- Remove hardcoded JWT secret fallback (random generated if unset)
- Remove BROKER_DEV_MODE auth bypass entirely
- Password comparison uses subtle.ConstantTimeCompare
- Remove wildcard CORS from SSE endpoint
- Update all tests to use API key auth instead of dev mode bypass
2025-12-24 10:56:15 -07:00
zeekay 9a3c3eee7b fix: remove wildcard CORS from SSE endpoint 2025-12-24 00:57:16 -07:00
zeekay 8d03ec839b test: add frontend exchange API tests 2025-12-24 20:51:08 -07:00
zeekay 4935ed6910 feat: add account resolver and frontend exchange API
Generic user→provider account resolution (replaces Alpaca-specific
mapping). Frontend-friendly /v1/exchange/* endpoints: assets with
type mapping, crypto prices, charts, orders, positions, portfolio.
All provider-agnostic — routes through resolver + registry.
2025-12-24 09:57:48 -07:00
zeekay a587cc73ea ci: add Cloud Build config for GCR image builds 2025-12-24 02:22:43 -07:00
zeekay 00396c97c7 docs: comprehensive README with full API reference
Complete endpoint documentation for all 80+ routes covering accounts,
orders, positions, smart routing, market data, transfers, journals,
documents, watchlists, events, risk, audit, and funding. Settlement
engine docs with KYC-tiered limits and margin thresholds. Provider
table, architecture diagram, configuration reference, Docker usage.
2025-12-24 00:56:27 -07:00
zeekay 4f757c05ba fix: pin Dockerfile to golang:1.26.1-alpine 2025-12-24 12:16:43 -07:00
zeekay f33d284d76 test: add comprehensive tests for API, audit, funding, marketdata
Integration tests for all HTTP endpoints (healthz, providers, risk,
audit, accounts). Unit tests for audit log (record, query, stats,
export, hooks, concurrency). Funding service tests. Market data feed
tests (BBO, multi-provider, subscribe, spread bps, concurrency).
Fix Dockerfile healthcheck endpoint (/health → /healthz).
Add version-aware Makefile with test-race and docker-push targets.
2025-12-22 11:15:22 -08:00
zeekay 7f7ac4b0a6 refactor: extract KYC/compliance to luxfi/compliance module
Remove KYC, application, and onboarding code from broker — now lives
in the standalone luxfi/compliance module. Broker remains a pure
trading router with admin auth, settlement, and multi-provider SOR.
Wire admin user config in main. Update LLM.md.
2025-12-18 16:07:33 -08:00
zeekay 24d7d0ceba feat: add prefunding pool and instant settlement engine
ATS prefunding pool for instant-buy execution while ACH settles.
Capital reservation with per-user/per-tx/utilization limits.
Margin monitoring with configurable warning/call/liquidation thresholds.
KYC-tiered instant buy limits (basic $250 → institutional $250k).
Full settlement lifecycle: reserve → execute → ACH clear/fail → settle/liquidate.
49 comprehensive tests including concurrency and end-to-end lifecycle.
2025-12-11 14:23:51 -08:00
zeekay 4585060a98 feat: add admin JWT auth with HMAC-SHA256 signing
Password hashing with SHA-256 + salt (never plaintext). JWT tokens
for admin dashboard access with role-based claims. Middleware for
protected route groups. Comprehensive tests for auth flows, token
validation, expiration, and tampering detection.
2025-12-04 09:42:17 -08:00
zeekay 8073fd565c test: add comprehensive unit tests for auth, risk, alpaca, types, router 2025-11-28 22:18:34 -08:00
zeekay f897cd1f9c feat: complete Alpaca Broker API — 100% endpoint coverage
Security fixes:
- Fix auth bypass: empty API key now returns 401 (unless BROKER_DEV_MODE=true)
- Fix risk engine recording $0 for all orders (now calculates qty*price)
- Fix hardcoded compliance fields in CreateAccount (pass-through from request)

P0 Trading Core:
- ReplaceOrder (PATCH), CancelAllOrders, GetPosition, ClosePosition, CloseAllPositions
- ListOrdersFiltered with status/limit/after/until/direction/nested params
- Extended CreateOrderRequest: trailing stops, bracket orders, extended hours

P1-P5 Complete API via composable interfaces:
- AccountManager: UpdateAccount, CloseAccount, GetAccountActivities
- DocumentManager: Upload, List, Get, Download documents
- JournalManager: Create, List, Get, Delete, Batch, ReverseBatch journals
- TransferExtended: CancelTransfer, DeleteACH, recipient bank CRUD
- CryptoDataProvider: GetCryptoBars/Quotes/Trades/Snapshots
- EventStreamer: SSE streaming for trade/account/transfer/journal events
- PortfolioAnalyzer: GetPortfolioHistory
- WatchlistManager: Full CRUD with asset management

Architecture: 8 optional capability interfaces on single Provider abstraction.
Providers implement what they support; router detects via type assertion.

Market data fixes:
- Crypto symbols now route to /v1beta3/crypto/us/ (not /v2/stocks/)
- GetBars pagination via next_page_token loop
2025-10-22 10:40:22 -07:00
zeekay feaa27adeb fix: Dockerfile — multi-stage build, Go 1.26, GOPRIVATE, healthcheck 2025-09-17 03:02:01 +00:00
zeekay 45efb158b1 chore: bump Go 1.26.0 → 1.26.1
Fixes 5 stdlib CVEs (html/template, os, net/url, crypto/x509 x2).
2025-09-07 14:19:39 -06:00
zeekay 3d61fc0ef2 docs: add LLM.md project guide 2025-08-14 18:34:07 -06:00
zeekay 45cc5d68c3 chore: update Go module dependencies 2025-08-11 13:20:10 -07:00
zeekay 6cc523855a feat: payment processor integration via hanzo/commerce
- Add hanzo/commerce v1.36.5 for Braintree, MPC payment processors
- Create pkg/funding service wrapping commerce processor registry
- Add deposit/withdraw/webhook endpoints under /v1/fund/
- Register Braintree processor with env-var config in brokerd
- Remove /api prefix from routes (subdomain routing in production)
- White-label: all config via env vars, multi-tenant ready
2025-08-02 12:30:00 +00:00
zeekay 0cd9e839a5 fix: add localhost:3001 to CORS allowed origins for CEX frontend 2025-08-01 16:15:37 -07:00
zeekay c0a7894279 docs: add README with provider inventory and API reference 2025-07-08 23:22:07 +00:00
zeekay c55bc151b7 fix: add node_modules and bin to .gitignore 2025-06-22 18:34:47 +00:00
zeekay 007cfd475d feat: federated broker with 16 providers, smart order routing, institutional trading
Providers: Alpaca, IBKR, BitGo, FalconX, Finix, SFOX, Coinbase, Binance,
Kraken, Gemini, Fireblocks, Circle, Tradier, Polygon, CurrencyCloud, LMAX

Features: fee-aware SOR, order splitting, pre-trade risk, audit logging,
consolidated market data, SSE streaming, auth middleware
2025-05-29 05:29:54 -05:00