Skip to content
Docs

Authentication SSO and Identity

  • API Key (X-API-Key / Bearer)
  • JWT Session (cookie + header)
  • OAuth2 / OIDC (multiple providers per org)
  • SAML 2.0 (native SP, @node-saml/node-saml)
  • LDAP / Active Directory (ldapts, with LDAPS + CA cert + skip-verify TLS)
  • User API Keys (ak_… format — unified per-user key with budgets/expiry)
  • SCIM v2 (per-org endpoint, token-authenticated)

A single hub-and-spoke admin wizard guides administrators through:

  1. Vendor selection (brand logos for Microsoft Entra ID, Okta, Google Workspace, Auth0, GitHub, generic OIDC, generic SAML, Active Directory / LDAP)
  2. Protocol setup (OIDC, SAML 2.0, LDAP — declarative protocol descriptors drive the form)
  3. Group mapping mode (Off / Auto / Mapped — see 16.6)
  4. Test connection + enable

The wizard exposes Auto-create and Enabled toggles per provider, supports draft saves (draftAt), and round-trips group-mapping configuration through the API.

OIDC discovery, auto-user creation, domain restriction, default roles, group claim key (groupClaimKey), logo URL, brand. Templates: Google, Microsoft, Okta, Auth0, GitHub, Custom OIDC. Admin APIs for CRUD and connection testing. Auto-created teams seed their budgets from the org’s default budget template (from Company Settings).

OAuth 2.1 flows supported:

  • Authorization Code + PKCE — interactive user login (browser-based clients, SPAs, mobile apps)
  • Implicit — legacy, discouraged but supported via OIDC discovery
  • Resource Owner Password Credentials — for migration from legacy LDAP-style flows
  • Refresh Token — silent re-auth without re-prompting

OAuth 2.0 client credentials flow (machine-to-machine): not implemented as a strict OAuth2 token endpoint. M2M access uses scoped API keys (ak_…) with TTL + rotation hooks, which are the OAuth2 equivalent in operational terms — see Section 16.8 + Section 35.

Scope-based access: incoming OIDC tokens carry scopes; gateway routes can require named scopes (e.g., model:gpt-4o.invoke, mcp:server-name.list) and reject calls missing them.

OpenAPI / Swagger documentation: the gateway auto-publishes OpenAPI 3.x specs for all routes (/api/admin/gateway/openapi.json, Swagger UI mounted at /admin/api-docs) including OAuth2 security schemes and scopes. Developers can Authorize → Try It Out against live endpoints from the docs page.

Endpoint Purpose
GET /api/auth/saml/metadata/:providerId Download SP metadata XML for IdP registration
GET /api/auth/saml/authorize/:providerId Generate SAML AuthnRequest and redirect to IdP
POST /api/auth/saml/callback/:providerId SAML assertion callback (ACS)
POST /api/auth/saml/logout SLO endpoint

Per-provider fields: samlEntryPoint, samlIssuer, samlCertificate, samlCallbackUrl. Requires signed assertions (SHA-256). Email, name, and group claims are extracted with configurable claim keys.

Per-org LdapProvider records with:

  • host, port, useSsl (LDAPS)
  • tlsCaCert (PEM upload), tlsRejectUnauthorized (skip-verify toggle)
  • bindDn + bindPassword, searchBase, searchFilter (default (sAMAccountName={{username}}))
  • groupSearchBase, groupAttribute (default memberOf)
  • usernameAttribute (default sAMAccountName), emailAttribute (default mail), nameAttribute (default displayName)
  • domainRestriction (limit by email domain)
  • autoCreateUsers, defaultRole

Login flow: POST /api/auth/ldap/login — discovers providers via GET /api/auth/ldap-providers/for-domain?email=…. Super-admin local fallback keeps the platform recoverable if directory binding fails.

Admin CRUD: /api/admin/ldap/providers (list/create), /:id (get/edit/delete), /:id/test (test bind), /:id/sync-groups (force group sync).

Target-org routing (multi-tenant LDAP): A single provider can route users into different organizations:

  • Provider-level default (targetOrganizationId)
  • Per-rule domain → org table (LdapOrgRoutingRule with signalType='domain', pattern like @example.com, lower priority wins)
  • Group-based routing reserved for a later phase

16.6 Group-to-Team Mapping (Unified across OIDC / SAML / LDAP)

Section titled “16.6 Group-to-Team Mapping (Unified across OIDC / SAML / LDAP)”

All three protocols share the SsoGroupMapping table and the applyGroupMappings() pipeline.

groupMappingMode per provider:

  • Off — no group sync; users get the provider’s defaultRole and no team
  • Auto — directory group names are parsed by autoTeamParseRule (regex / pattern), an autoDefaultRole is assigned, and an autoDefaultBudgetTemplateId seeds the team budget. Mappings are synthesized on the fly at login time
  • Mapped — admin-defined SsoGroupMapping rows: (provider, adGroupName) → (teamId | autoTeamName, orgRole, budgetTemplateId, priority)

Group mappings apply at first login (and on subsequent logins to update memberships) and are managed via a dedicated UI panel.

Endpoint format: /scim/v2/:orgId/… — every org gets its own SCIM tenant.

Endpoint RFC 7644 Purpose
GET /scim/v2/:orgId/ServiceProviderConfig Discovery Public
GET /scim/v2/:orgId/ResourceTypes Discovery Public
GET /scim/v2/:orgId/Schemas Discovery Public
GET / POST / PUT / PATCH / DELETE /scim/v2/:orgId/Users[/:id] RFC 7644 Token-auth
GET / POST / PATCH / DELETE /scim/v2/:orgId/Groups[/:id] RFC 7644 Token-auth

Accepts both application/scim+json (spec) and application/json (Okta).

Per-org configuration (ScimConfig):

  • enabled
  • groupSyncMode — Off / Auto / Mapped (same semantics as 16.6)
  • groupParseRule
  • defaultOrgRole, defaultBudgetTemplateId

Token management (ScimToken): named tokens with hashed storage, reveal-once display, prefix/suffix masking, lastUsedAt / lastUsedIp telemetry, expiry, revoke. Admin UI provides a generate-token modal and a tokens list. Admin APIs: /api/admin/scim/config, /api/admin/scim/tokens.

Users carry an externalId so IdP-side ID changes don’t fork accounts.

Failed-login lockout, forced password change, admin transfer tracking, key expiry, rotation alerts (90-day default).