Skip to main content
Every data-plane and dashboard API call authenticates with a project API key sent as an x-api-key header. The dashboard, the Python SDK, CI pipelines, and OpenTelemetry exporters all use the same key. The exceptions appear later on this page: the admin endpoints take x-admin-token, /metrics can take its own bearer token, and in AGENTX_AUTH=enabled mode dashboard requests ride a session cookie instead.

Where keys come from

  • Engine startup log: the line Default project API key: agtx_local_... prints on every boot. This is the canonical copy source for SDK and CI callers on a fresh instance.
  • GET /api/v1/auth/config: in the default (no-auth) mode, this unauthenticated endpoint includes the default project’s apiKey - a deliberate tradeoff: anyone who can reach the port already owns the instance in practice, so bind it accordingly (see Security model). In AGENTX_AUTH=enabled mode, no key is ever handed out this way.
  • Dashboard: once connected, Settings → API key shows the current project’s key, and each project you create gets its own key (the project switcher moves between them).

Dashboard: connecting

The default self-host mode has no user accounts. On first visit the dashboard reads /api/v1/auth/config, receives the default project’s key, and connects automatically - a fresh install lands on a working screen with zero setup. The key is kept in that browser’s local storage and attached to every request; the sidebar’s Disconnect button forgets it. A manual connect screen (paste a key from the startup log) remains as a fallback for older engines and for connecting with a specific project’s key.

SDK

The three modes

Multi-user mode: AGENTX_AUTH=enabled

For a shared instance, start the engine with AGENTX_AUTH=enabled. This switches the dashboard from the connect screen to real accounts:
  • First boot shows an owner-setup screen - the first account created becomes the organization owner and claims the existing projects. Later sign-ups get NO membership on their own: teammates join by accepting an invitation (Settings → Team), so an exposed port cannot hand your projects to a stranger who self-registers. Set AGENTX_OPEN_SIGNUP=true to restore auto-join on a closed network.
  • Dashboard requests ride the session cookie; project keys are handed out through the session-guarded /projects listing after sign-in, never anonymously.
  • SDK / CI / OTel callers are unchanged - they still authenticate with a project API key from Settings → API key.

Multi-tenant mode: AGENTX_MULTI_TENANT=true

Add AGENTX_MULTI_TENANT=true (with auth enabled) for a deployment where strangers sign up - each signup creates its own organization with a seeded default project, and organizations are hard-isolated: separate projects and data, separate LLM provider keys (Settings → LLM Providers writes the org’s own row; the process env is never used for tenant judge calls), and separate pricing-catalog additions. Teams and invitations (Settings → Team): owners and admins invite teammates by email - creating an invitation returns a link to send; the teammate signs in (or signs up) with the invited email and the link adds them to the organization. Invitations are single-use, bound to the invited email, and expire after 7 days. The owner can’t be removed; admins can invite and remove members. Set AGENTX_PUBLIC_URL so invitation links carry your real domain.

Email, password reset, and social sign-in

All of these are optional and advertised to the dashboard through /auth/config, so the sign-in screen only shows what the engine actually supports:
  • Email delivery: configure AGENTX_RESEND_API_KEY (Resend) or AGENTX_SMTP_URL (any SMTP server), plus AGENTX_EMAIL_FROM. With a transport configured, invitation emails are sent automatically and the sign-in screen gains a Forgot password? link that emails a reset link (/reset-password in the dashboard).
  • Email verification: add AGENTX_REQUIRE_EMAIL_VERIFICATION=true to make new accounts verify their address before the first sign-in.
  • Social sign-in: set AGENTX_GOOGLE_CLIENT_ID/AGENTX_GOOGLE_CLIENT_SECRET and/or AGENTX_GITHUB_CLIENT_ID/AGENTX_GITHUB_CLIENT_SECRET to add “Continue with Google/GitHub” buttons. Register the OAuth callback as <AGENTX_PUBLIC_URL>/api/v1/auth/callback/<provider>.
  • Enterprise SSO (generic OIDC): set AGENTX_OIDC_ISSUER, AGENTX_OIDC_CLIENT_ID, and AGENTX_OIDC_CLIENT_SECRET to add an SSO button (label it with AGENTX_OIDC_NAME, e.g. “Okta”). Works with any IdP that serves OIDC discovery - Okta, Microsoft Entra ID, Auth0, Google Workspace, Keycloak. Register the callback as <AGENTX_PUBLIC_URL>/api/v1/auth/callback/oidc - the same shape as the social providers. (Deployments upgraded from engines older than better-auth 1.7 must update the redirect URI registered with their IdP: it used to be /api/v1/auth/oauth2/callback/oidc.) SAML and SCIM are not supported; OIDC is the supported enterprise door.

Operating a multi-tenant deployment

  • Quotas: AGENTX_QUOTA_JUDGE_CALLS_PER_DAY caps judge LLM spend (per organization in multi-tenant mode) and AGENTX_QUOTA_TRACES_PER_DAY caps root-trace ingest per project. Hitting the trace quota returns a 429 naming the limit; a capped judge call degrades like a judge outage (the affected result is stored as skipped, with the quota message as its justification). A third cap, AGENTX_QUOTA_ONLINE_JUDGE_CALLS_PER_DAY, budgets live judge calls per project on top of the global judge quota - see Configuration. All three reset at midnight UTC and are unlimited when unset.
  • Admin overview: set AGENTX_ADMIN_TOKEN and call GET /api/v1/admin/overview with an x-admin-token header for per-organization members, projects, and 24-hour judge/trace usage. The endpoint 404s when the token is unset.
  • Organization deletion: an owner can delete their organization from the API (DELETE /api/v1/auth-org/organizations/:orgId with the body {"confirmName": "<org name>"} as confirmation) - every project and all of its data go with it. User accounts survive; in multi-tenant mode a returning orphaned account simply gets a fresh organization.

Putting it together

A complete multi-tenant cloud posture is just environment variables on the same engine binary or Docker image the single-tenant install uses:
Related engine variables (AGENTX_PUBLIC_URL, AGENTX_TRUSTED_ORIGINS, the mailer, quota, and admin variables) are listed in Configuration.

Security model

A project API key grants full access to that project’s data - treat it like any other secret: environment variables and CI secret stores, never source control. In default mode the engine trusts the network boundary (“if you can reach the port, you hold a key you were given”), so bind it to localhost or a private network, or turn on AGENTX_AUTH=enabled before exposing it more widely.