Authentication.
Aria authenticates end users with OAuth and issues a database-backed session cookie. There is no API key system today.
Honest today, not tomorrow
Programmatic authentication — API keys, OAuth public clients, client credentials — is not supported. Every request must carry a session cookie belonging to a signed-in, onboarded user. The remainder of this page describes what is actually in production; the final section describes what is planned.
Session model
Corvana uses NextAuth v5 with a database session strategy. When a user signs in, the server writes a Session row to Postgres and sets an HTTP-only cookie pointing at it. The session is resolved against the database on every request — there is no JWT round-trip.
Cookies
authjs.session-tokenSession cookie in local and preview environments.
__Secure-authjs.session-tokenSession cookie in production. Only sent over HTTPS.
Browsers include the cookie automatically after sign-in. Programmatic clients must forward it verbatim.
OAuth providers
- Google — workspace accounts supported out of the box.
- Microsoft Entra — single-tenant or multi-tenant configurations at provisioning.
- GitHub — for developer-account sign-in.
Additional enterprise identity providers (Okta, Auth0, Ping, Azure SAML) are configured per customer at provisioning. Contact hello@corvanahq.com before an enterprise rollout.
Onboarding gate
A signed-in user with no User.onboardedAt is treated as not yet reachable. The live chat endpoint rejects the request with 403 NOT_ONBOARDED; the UI redirects to /onboarding for the three-step capture (company, role, goal). Until onboarding completes, there is no Organization row, which means Aria cannot compose the company-context layer of the system prompt.
Calling the live chat endpoint
Call from the browser after sign-in — the cookie is included automatically:
const res = await fetch("/api/chat", {
method: "POST",
credentials: "include",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
messages: [
{ role: "user", content: "What's the largest dollar lever we've surfaced so far?" },
],
}),
});
if (res.status === 401) window.location.assign("/login");Session lifecycle
Sessions rotate on an idle-sliding window. Any active request refreshes the session row; the cookie expires after a hard ceiling of 30 days. Calls with an expired or revoked session return 401 UNAUTHENTICATED as plain text. Clients should treat 401 as an unconditional redirect to /login.
Programmatic access Planned
Server-to-server authentication is designed but not shipped. The target shape is a scoped service credential issued from an organization's admin dashboard:
POST /api/chat HTTP/1.1
Host: app.corvanahq.com
Authorization: Bearer frd_svc_live_abc123…
Content-Type: application/json
{ "messages": [ … ] }Credentials will be scoped per organization and per intent (chat, retrieval, admin). There will never be a client-side credential with broad scope — if you need to build a public integration, wait for the OAuth public-client flow landing alongside it.
Continue with Live chat or the Errors reference.