Browser integration through a backend proxy
Keep service credentials on a backend and map browser users to authorised resources.
The React starter sends browser requests to /api/q on the same origin. A Node backend holds the Q credential and forwards only bounded answer operations. The browser receives an application CSRF token, not the upstream key.
Local reference flow
- The loopback server creates a ten-minute local session through an origin-checked POST
/session. - Its session ID is an HttpOnly, SameSite=Strict cookie. A distinct random CSRF token is returned to the page and passed to
QProvideras the proxy credential. - The proxy validates Host, Origin, Fetch Metadata, cookie, CSRF token and expiry. It allows up to 32 active sessions, 30 requests per session and one active answer POST per session.
- It permits version-1 answer requests with query/mode/history only, adds required tool approvals server-side, and rejects caller-selected tenant/user/resource/tool fields. Bodies are limited to 32 KiB.
- It records the run ID from the upstream handshake. Replay and approval requests must belong to the same local session. A different session cannot poll or decide that run even though the demonstration backend uses one Q credential.
- Upstream requests have a 120-second deadline; redirects are refused. Credentials/cookies are not forwarded from browser to Q. Only selected stream/response headers return to the browser. Streaming preserves bytes and backpressure; disconnect aborts the observer request, not Q's bounded producer.
The proxy forwards explicit version-bound approval decisions for owned runs; it never approves by default. The Q approval store remains authoritative for action version, expiry and consumption. Session expiry may end access before Q's replay retention expires; signing in again does not transfer old run ownership automatically.
Production integration
This is a runnable loopback development example. It does not authenticate real users. It deliberately binds 127.0.0.1 and rejects other Host values. Do not expose it through a tunnel or public reverse proxy as an application login service.
A deployed adapter must replace local session creation with the application's established authentication, select the correct tenant/user credential or authorised delegation on the server, and authorise every resource and run. Use HTTPS, Secure cookies, origin/CSRF validation, persistent session/run ownership, distributed quotas and request auditing without prompts/credentials. Keep the operation/body allowlist and redirect/deadline protections. A global shared key plus a browser-supplied tenant ID is not tenant isolation.
The current starter uses a single synthetic development tenant and in-memory sessions. It makes no cross-process session recovery guarantee. Never replace the session token with VITE_Q_API_KEY, NEXT_PUBLIC_Q_API_KEY or a service key in frontend source. Authentication explains the difference between test-mode keys, tenant authorisation and the local synthetic sandbox.