Three auth regimes on one router
Eye-Key, user JWT, Atlas WS — one router, three contracts, three threat models.

DEINO’s API runs on one router, and that router carries three auth regimes: the Eye-Key API for developers, user JWTs for the console, and the Atlas WebSocket for World Monitor. Three contracts, three threat models, one router. The separation is the design — not a complication, a discipline.
Each regime protects a different audience against a different threat. The Eye-Key is the developer surface — a long-lived API key, per-key rate-limited, used by SDKs and integrations. User JWTs are the console surface — short-lived access tokens, refresh-rotated, session-bound, IP-bindable, issued by deino-warden for users who log in. The Atlas WebSocket is the World Monitor surface — user-JWT-authed via query token, with its own per-user connection limiting because a stream is not a request. Three regimes because three problems; one router because the composition root is one place.
The Eye-Key: one key, shown once
The Eye-Key is the developer surface. It is a key — HMAC-signed, fingerprinted, rate-limited per key — and its plaintext is shown once, in memory, and never touches disk (INV-2). The developer gets the key once, stores it, and uses it to call the API. Per-key rate limiting means one key cannot drown the platform; the rate limit is the boundary, and the key is the identity. This is the regime for machines talking to machines.
User JWTs: deino-warden
User auth is deino-warden’s job. A user logs in — password, Google OAuth, or refresh — and warden issues a JWT access token and a refresh token. Access tokens are short-lived; refresh tokens rotate them; sessions are recorded and can be IP-bound so a token stolen from one IP is useless on another. This is the regime for people looking at a console — the threat is credential theft and session hijack, and the defenses are rotation, expiry, and binding. The console routes (/api/v1/auth/*) live here, and the user-JWT gates the dashboards.

Three regimes because three problems. One router because the composition root is one place. The separation is the discipline, not a complication.
The Atlas WS: a stream is not a request
World Monitor’s realtime endpoint is a WebSocket — GET /api/v1/atlas/ws — and a stream does not behave like a request. Auth is via query token (user JWT, not Eye-Key) because a WS handshake is not a header-friendly place; connection limiting is per-user because a stream holds resources a request does not. The Atlas WS is authed but not per-request rate-limited, because the limit is the connection, not the call. Tide SSE is the same shape: authed, not per-request rate-limited. The stream regimes are separate from the request regimes because the resource model is different.
Why not one regime
One regime for everything would be simpler, and simpler would be wrong. A long-lived API key is appropriate for an SDK and inappropriate for a console session; a rotating JWT is appropriate for a person and impractical for a machine integration; a per-user connection cap is essential for a stream and meaningless for a request. Each regime is shaped by its threat. Forcing them into one contract means one of them is under-protected or over-engineered. Three regimes is the honest count — the router composes them, and the composition is the architecture.
- Eye-Key: developer/SDK surface, per-key rate-limited, plaintext shown once (INV-2). Machines.
- User JWT (deino-warden): access/refresh rotation, sessions, IP-binding, Google OAuth. People.
- Atlas WS: user-JWT via query token, per-user connection caps, not per-request rate-limited. Streams.
- Tide SSE: authed, not per-request rate-limited — same shape as Atlas, a stream is not a request.
The threat behind each door
The Eye-Key threat is key exfiltration and abuse — the defenses are the single showing, the per-key rate limit, and the fingerprint. The user-JWT threat is credential theft and session hijack — the defenses are rotation, expiry, IP-binding. The Atlas WS threat is resource exhaustion — the defenses are per-user connection caps and viewport-only broadcast. Three threats, three defenses, one router. We are pre-revenue, building the POC; all three regimes run, and the security of each is a property of its contract, not a promise on a slide.
A stream is not a request, a machine is not a person, and a long-lived key is not a rotating session. One regime for everything is simpler, and simpler is wrong. Three regimes is the honest count.
— auth architecture note