When ENVIRONMENT=local or ENABLE_PUBLIC_DATA is set, register Kraken
and Gemini without API keys. Their public endpoints provide real-time
crypto prices without authentication.
Asset struct: add overnight_tradable, overnight_halted,
fractional_eh_enabled, min_order_size, price_increment,
min_trade_increment — parsed from Alpaca assets API.
CreateOrder: add pre-flight validation:
- Notional max 2 decimal places, qty max 9 decimal places
- Crypto: TIF must be gtc or ioc (rejects day)
- Crypto: max $200k notional, min $1 buy notional
- Crypto: min qty 0.000000002
CreateOrderRequest: add AssetClass field for asset-class-aware
validation without symbol heuristics.
Addresses Alpaca Tech Sign Off items across all 5 checklists.
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
- 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
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.
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
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.
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.
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.
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.
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)