Authentication
Arkenos uses Better Auth for authentication, with a clear separation between auth data and business data.Architecture
Two User Tables
| Table | Owned by | Contains |
|---|---|---|
"user" | Better Auth | Auth credentials, email verification, session management |
"users" | Backend | Business data references — all FKs (agents, sessions, API keys) point here |
users table is an auth-agnostic abstraction layer. If the auth provider changes, only the sync logic updates — all business data stays intact.
Auto-Sync Flow
- User signs up → Better Auth creates a row in
"user"table - User makes first API request → backend receives Bearer token
verify_session_token()validates the token against Better Auth’s"session"table- If no matching
usersrow exists, it reads from"user"and auto-creates one - Same pattern for organizations:
_auto_create_org_from_ba()syncs Better Auth orgs toorganizations
Authentication Methods
Browser → Backend (Session Token)
Dashboard API calls include a Bearer token from the Better Auth session:"session" table (single indexed query).
Agent → Backend (X-User-Id)
The agent worker uses a trusted server-to-server header:Organization Context
Every API request resolves an organization via (in priority order):x-org-idheader — explicit org selection from the frontendactiveOrganizationIdfrom the Better Auth session- User’s first org membership (fallback for single-org users)
organizations table, it is auto-created.
Frontend Auth Setup
Better Auth is configured infrontend/src/lib/auth.ts with:
- Email/password authentication
- Organization plugin (multi-tenancy)
nextCookiesplugin (proper cookie handling for Next.js server components)- Auto-migration of Better Auth tables on startup
Post-Login Navigation
After sign-in, the frontend useswindow.location.href (not router.push) to navigate to the dashboard. This forces a full page load, ensuring auth cookies are properly sent to server components during the initial render.
Key Files
| File | Purpose |
|---|---|
frontend/src/lib/auth.ts | Better Auth server config (plugins, DB connection) |
frontend/src/lib/auth-client.ts | Better Auth client SDK (signIn, signUp, useSession) |
frontend/src/lib/server-auth.ts | Server component auth helper (getServerAuthHeaders) |
frontend/src/lib/auth-headers.ts | Client component auth hook (useAuthHeaders) |
backend/app/dependencies.py | Session verification, user/org resolution, auto-creation |
backend/app/main.py | UserContextMiddleware (sets user/org context per request) |