Security Overview
Draft for owner/legal review. This page describes the application as shipped in Hydra v39 (1.12). Items marked [OWNER TO COMPLETE] must be filled in by the person or company operating this site before the page is relied on. Nothing here has been reviewed by a lawyer.
What is in place in Hydra v39, and what is not. This is an honest inventory, not a certification; Hydra has no SOC 2, ISO 27001 or similar certification.
In place
- HTTPS everywhere (Netlify-managed TLS); HSTS, nosniff, frame-ancestors and referrer policy headers.
- Passwords hashed with scrypt and a per-user salt; constant-time comparisons; per-IP and per-account sign-in limits; enumeration-resistant sign-up and sign-in messages.
- Signed, expiring (30-day), HttpOnly, Secure, SameSite=Lax session cookies carrying a per-account session version — "sign out everywhere", password change and admin revocation invalidate every existing session. Cross-site state-changing requests are refused (Origin / Sec-Fetch-Site check).
- Server-side authorisation on every endpoint: guests cannot spend the operator's keys; the admin role comes only from the server's configuration and is checked on every admin call.
- Money protection: a short free preview for visitors, then a subscription, per-account and site-wide daily/monthly budgets, a per-request worst-case cost cap, atomic budget reservations before each request (settled with actual usage, expiring if abandoned), rate limits per account and per IP, a site-wide emergency pause that fails closed when its state can't be read, and an audit trail of admin actions.
- Your own API keys and connector tokens are encrypted at rest (AES-256-GCM, key derived from the server secret) and masked in every response; a key you supply is only ever sent to that provider's own endpoint.
- Server-side requests to URLs you or a model choose (fetch_url, custom APIs, MCP, OAuth) are checked by name and by resolved IP against private ranges, pinned to the checked address (no DNS rebinding), refuse redirects, strip credentials across origins and cap response sizes.
- Model-run JavaScript executes in an isolated worker with no network, no filesystem and a hard timeout; Python runs in your browser (Pyodide), never on the server.
- Web pages and search results given to the model are wrapped as untrusted data with instructions not to follow directions found in them.
- Dependencies audited (
npm audit --omit=dev= 0 at release); TypeScript strict; ESLint.
Not in place / limitations
- No end-to-end encryption: the server decrypts to talk to providers.
- No email verification or multi-factor authentication (no email provider is configured; the free preview and the subscription limit what a new account can spend). [OWNER TO COMPLETE] if the operator adds an email service.
- Budgets are estimates from reported token counts at list prices; the provider's invoice is authoritative. Set hard spend limits at each provider too.
- The Content Security Policy allows inline scripts and scripts from any HTTPS origin, because the app renders user-built sites in sandboxed iframes (which inherit the policy and load their own CDN libraries) and loads Pyodide from a CDN. It still forbids framing by other sites, plugins and base-tag changes.
- Admins can see account emails, spend and status, never conversations. There is no technical control stopping the operator reading the blob store directly.
Reporting a vulnerability
Email [OWNER TO COMPLETE]. Please do not test against other people's accounts.