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.
- 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
- 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)
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.
- 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
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.
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.
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":[...]}.
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.
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.
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.
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.
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.