[Five Walls Deep: HOOX Security as Concentric Rings]
Five security rings plus mesh hardening: two-phase DO idempotency, RateLimiterStore, chat allowlists—each with a failure mode.
Sources: papers/sections/05-security.tex, architecture overview 5-layer model, docs/devops/security/overview.mdx, gateway mesh hardening v0.13.
Thesis
HOOX security is not a single middleware file. It is five concentric corridors, thickened by mesh controls on the gateway path. Traffic that reaches an exchange signature has already survived edge filtering, webhook auth, isolation, internal auth, and (on the success path) a two-phase idempotency reservation. Each layer has a declared failure mode.
Enterprise does not replace this model; it thickens it (essay 13).
1. The five layers
[1 WAF / IP allow-list]
→ [2 Webhook API key + rate limit + kill switch]
→ [3 Service Binding isolation]
→ [4 X-Internal-Auth-Key]
→ [5 Two-phase IdempotencyStore (+ RateLimiterStore)]
| Layer | Control | Failure mode |
|---|---|---|
| 1 | WAF + TradingView® IP CIDRs (KV-extensible) | Drop / 403 at edge |
| 2 | apiKey + timing-safe compare; 64 KiB cap; DO/KV rate limit; kill switch; notify chat allowlist |
401 / 403 / 413 / 429 / 503 |
| 3 | No public routes on internal workers | Unreachable |
| 4 | requireInternalAuth on binding routes |
401 fail-closed |
| 5 | Idempotency DO reserve/commit/release | 409 duplicate; 503 if DO missing |
2. Asymmetry is intentional
Authentication fails closed. Missing idempotency store fails closed.
Soft-fails after reserve release so a legitimate retry can proceed.
A forged trade is not recoverable the way a brief refused trade is.
That sentence is the open-core threat-model thesis after v0.13.
3. Secondary ingress & data guards
Email: Mailgun HMAC (timestamp + token), constant-time compare, same Zod trade schema, then binding to trade-worker.
D1: Named RPCs for hot paths (list-signals, list-system-logs, list-open-positions, insert/upsert templates). Free-form /query stays SELECT-only. Table allowlists and known CONFIG_KV prefixes for dashboard settings. Compromise of one binding ≠ DROP TABLE.
Telegram: Outbound/inbound chatId allowlists when configured — unlisted IDs fail closed.
4. Secrets, crypto & background work
- Secrets in Wrangler secret bindings, never KV/D1
CryptoKeyimport once per isolate; HMAC-SHA256 per venue- WS DO state: handles only, not signing material; REST-only order placement
- Rate limit: 10 trades / 60 s per session via
RateLimiterStoreDO (KV/memory fallback) - Background D1/analytics/notify: mesh-wide
safeWaitUntil - Response hardening: CSP, frame options, nosniff, HSTS via shared middleware
5. Operator checklist
- Rotate webhook and internal keys as secrets.
- Deploy DO migrations
v1(IdempotencyStore) andv2(RateLimiterStore) — seeworkers/hoox-worker/DEPLOY.md. - Keep TradingView® IP ranges and Telegram chat allowlists current.
- Treat kill switch as production control.
- Run
tests/security/in CI. - Never leave probe short-circuits on a path that can sign live orders without flags.
Previous: Storage · Next: Observability