Conduit
Conduit
Docsllms.txtHostingGitHubIntroduction

Getting Started

OverviewInstall ConduitMCP SetupYour First AppStart with AI

Learn

ArchitectureClient vs Admin APIConfiguration

Modules

OverviewAuthenticationAuthorizationDatabaseStorageCommunicationsChatRouterFunctions

Guides

Next.js IntegrationReBAC Team ScopingGitOps State Export

Deployment

Deployment OverviewDocker ComposeKubernetes and HelmLocal from SourceContainer Images

Reference

CLI ReferenceClient APIAdmin APIEnvironment VariablesMCP Tools

Resources

Migration v0.16 → v0.17Legacy DocumentationChangelogFAQGlossaryContributing

Authentication

Users, local/OAuth login, tokens, teams, 2FA, and sudo for sensitive operations.

Apps need sign-up, login, token lifecycle, and optional multi-tenant membership without building auth from scratch. The authentication module handles user accounts, JWT access/refresh tokens, OAuth providers, teams, magic links, and 2FA. Application runtime code uses the Client API with user bearer tokens; provisioning uses the Admin API or MCP.

For AI agents

Machine-to-machine and operator automation use Admin API tokens (cdt_ prefix) — not Client API service accounts. See Client vs Admin API.

Use cases

User sign-up and login

Email/password or OAuth with JWT access and refresh tokens

Multi-tenant B2B

Teams with hierarchy, invites, and ReBAC-backed membership

Secure web apps

Server-side token vault — tokens never in browser storage

Sensitive account changes

Sudo mode after fresh login gates password, email, 2FA, and team deletion

CI and provisioning

Admin API `cdt_` tokens or MCP for operator workflows — not end-user tokens

Capabilities

  • Local register/login
  • OAuth (Google, GitHub, Apple, Microsoft, Facebook, Slack, GitLab, …)
  • Access + refresh tokens (JWT)
  • Sudo mode for destructive/sensitive routes
  • Magic link login
  • 2FA (authenticator + SMS)
  • 2FA backup codes (config-gated)
  • Teams, invites, and sub-teams
  • Email verification & password reset
  • User profile extension fields
  • Anonymous users (optional)
  • Account linking (same email across providers)

Example: Register, login, and invite a teammate

Walkthrough

  1. Enable the authentication module and local strategy via MCP `patch_config_authentication`
  2. Set `teams.enabled: true` and configure invites if needed
  3. Register a user with POST /authentication/local/new (pass `invitationToken` when invites are required)
  4. Log in with POST /authentication/local — store `{ accessToken, refreshToken }` server-side
  5. Create a team via POST /authentication/teams or MCP `post_authentication_teams`
  6. Invite a teammate with POST /authentication/teams/:teamId/invite
Register
curl -X POST http://localhost:3000/authentication/local/new \
-H "Content-Type: application/json" \
-d '{"email":"dev@example.com","password":"SecurePass123!"}'
Login
curl -X POST http://localhost:3000/authentication/local \
-H "Content-Type: application/json" \
-d '{"email":"dev@example.com","password":"SecurePass123!"}'

Register returns { user } only — the user must log in separately for tokens.

How it works

Token lifecycle

Access tokens are JWTs (default 1h via accessTokens.expiryPeriod). The payload includes:

ClaimMeaning
idUser ID
authorizedtrue when login is complete (including 2FA if enabled)
sudotrue on tokens issued from a fresh login — required for sensitive routes

When refreshTokens.enabled is true, POST /authentication/renew rotates the refresh token and issues a new pair. Renewed tokens set sudo: false — the user must re-authenticate for destructive operations. Blocked users (active: false) cannot renew or log in.

clients.multipleUserSessions and clients.multipleClientLogins control whether new logins invalidate existing tokens per client or globally.

Sudo mode

Several routes require jwtPayload.sudo === true on the access token. Sudo is granted only when:

  1. The user completed login (and 2FA, if enabled), and
  2. Tokens were issued from a login flow — not from /authentication/renew

If sudo is missing, the API returns PERMISSION_DENIED with "Re-login required to enter sudo mode".

RouteAction
DELETE /authentication/userDelete own account
POST /authentication/local/change-passwordChange password
POST /authentication/local/change-emailChange email
PUT /authentication/twoFa/enableEnable 2FA
PUT /authentication/twoFa/disableDisable 2FA
GET /authentication/twoFa/generateGenerate backup codes
DELETE /authentication/teams/:teamIdDelete team

Pattern: prompt the user to log in again before sensitive settings changes; use the new access token for the sudo-gated call.

Application token storage

Web / Next.js: Store { accessToken, refreshToken } in a server-side vault (Redis). The browser holds only an opaque session cookie. On 401, renew once and retry. See the Next.js guide.

Mobile: Platform secure storage (Keychain, SecureStore) when no server vault exists.

Never persist tokens in localStorage or sessionStorage.

Two-factor authentication (2FA)

Enable globally with twoFa.enabled. Per-method toggles:

Config keyMethod valueNotes
twoFa.methods.authenticator"authenticator"TOTP via authenticator app
twoFa.methods.sms"sms"SMS via the communications module — use method name sms, not phone

Login with 2FA: POST /authentication/local returns a challenge (SMS sent or OTP required) instead of full tokens. Complete with POST /authentication/twoFa/verify and the code.

Enable flow: PUT /authentication/twoFa/enable with { "method": "sms", "phoneNumber": "+1..." } or { "method": "authenticator" } (requires sudo). Confirm via POST /authentication/twoFa/enable/verify.

Backup codes: When twoFa.backUpCodes.enabled is true, these routes are registered:

RoutePurpose
GET /authentication/twoFa/generateGenerate 10 one-time codes (requires sudo)
POST /authentication/twoFa/recoverRecover access with an 8-digit backup code during login

When twoFa.backUpCodes.enabled is false, backup-code routes are not exposed.

Teams

Enable with teams.enabled. Teams register as a built-in ReBAC resource (Team) with relations member, owner, and team-scoped permissions. See Authorization and ReBAC team scoping.

ConceptBehavior
Flat B2BEach root Team (parentTeam: null) is a tenant boundary
Sub-teamsparentTeam on create sets Team:parent#owner@Team:child for permission inheritance
Invitesteams.invites.enabled — email invites with invitationToken on register/OAuth
Default teamteams.enableDefaultTeam auto-creates a personal team per user

Key Client API routes (all require authentication):

OperationPath
List my teamsGET /authentication/teams
Create teamPOST /authentication/teams
Get / update / delete teamGET|PATCH|DELETE /authentication/teams/:teamId
MembersGET|PATCH|DELETE /authentication/teams/:teamId/members
Sub-teamsGET /authentication/teams/:teamId/teams
Invite userPOST /authentication/teams/:teamId/invite
Accept inviteGET /authentication/teams/invite/accept?invitationToken=…
Pending invitesGET /authentication/teams/invites

Team delete requires sudo. Admin CRUD uses MCP tools like get_authentication_teams and post_authentication_teams.

OAuth

When a provider is enabled with clientId + clientSecret, routes are registered per provider:

StepPath
Start redirect flowGET /authentication/init/{provider}
Native/mobile initGET /authentication/initNative/{provider}
IdP callbackGET /authentication/hook/{provider}

Supported providers include Google, GitHub, Apple, Microsoft, Facebook, Slack, GitLab, Twitter, Twitch, Figma, Reddit, Bitbucket, LinkedIn, and Metamask (when configured).

Pass invitationToken and redirectUri on init to join a team during OAuth sign-up. Tokens return in JSON or httpOnly cookies depending on accessTokens.setCookie / refreshTokens.setCookie. redirectUris.whitelistedUris restricts post-auth redirects.

Machine auth (service accounts removed in v0.17)

v0.17 removes Client API service accounts (POST /authentication/service) as a breaking change. The Service collection is dropped on authentication module startup migration. For automation, CI, and MCP clients, use Admin API tokens instead:

  • Create cdt_ API tokens via Admin API (POST /api-tokens) or MCP post_apitokens
  • Authenticate MCP with Authorization: Bearer <cdt_token>
  • Never embed admin tokens in application runtime code or browser config

Until you upgrade from v0.16, legacy deployments may still expose service-account login behind service.enabled — plan migration before promoting v0.17. See Migration v0.16 → v0.17.

Configure

Patch module config via MCP patch_config_authentication:

KeyDefaultMeaning
accessTokens.expiryPeriod3600000 (1h)Access JWT lifetime (ms)
accessTokens.setCookiefalseReturn tokens as httpOnly cookies
refreshTokens.enabledtrueEnable /authentication/renew
refreshTokens.expiryPeriod604800000 (7d)Refresh token lifetime
local.enabledtrueEmail/password strategy
local.verification.requiredfalseBlock login until email verified
local.verification.methodlinklink or code verification
teams.enabledfalseTeam routes and team-scoped ReBAC
teams.invites.enabledfalseEmail team invitations
teams.enableDefaultTeamfalseAuto-create personal team on register
twoFa.enabledfalseGlobal 2FA toggle
twoFa.methods.smsfalseSMS 2FA (requires communications module)
twoFa.methods.authenticatortrueTOTP authenticator 2FA
twoFa.backUpCodes.enabledtrueExpose backup-code generate/recover routes
magic_link.enabledfalsePasswordless email login
anonymousUsers.enabledfalseAnonymous user registration

OAuth providers need clientId + clientSecret per provider under config.{provider}.enabled.

Local and OAuth routes require router client id/secret in request context (Conduit router client credentials). Email verification, magic links, and invite emails require the communications module.

Client API

OperationPath
RegisterPOST /authentication/local/new
LoginPOST /authentication/local
RenewPOST /authentication/renew
LogoutPOST /authentication/logout
Current userGET /authentication/user
Update userPATCH /authentication/user
Delete userDELETE /authentication/user (sudo)
Change passwordPOST /authentication/local/change-password (sudo)
Forgot / reset passwordPOST /authentication/forgot-password, POST /authentication/reset-password
Magic linkPOST /authentication/magic-link
OAuth initGET /authentication/init/{provider}
2FA verifyPOST /authentication/twoFa/verify
2FA enable / disablePUT /authentication/twoFa/enable, PUT /authentication/twoFa/disable (sudo)
2FA backup codesGET /authentication/twoFa/generate, POST /authentication/twoFa/recover (when twoFa.backUpCodes.enabled)
TeamsGET /authentication/teams, POST /authentication/teams, GET /authentication/teams/:teamId, …

MCP

Enable with ?modules=authentication in your MCP server URL.

ToolPurpose
get_authentication_usersList users
post_authentication_usersCreate user (admin)
get_authentication_teamsList teams
post_authentication_teamsCreate team
patch_config_authenticationToken, OAuth, team, and 2FA settings

For operator automation, prefer cdt_ API tokens over legacy service-account config. See MCP setup.

Next steps

  • Your first app
  • Next.js integration
  • Authorization (ReBAC)
  • ReBAC team scoping
  • Admin API tokens

Overview

Conduit Platform modules overview.

Authorization

ReBAC resources, relations, permissions, and scope.

On this page

Use casesCapabilitiesExample: Register, login, and invite a teammateHow it worksConfigureClient APIMCP