Authentication Module

Complete API reference for sso.auth module - OAuth flows, device authentication, token management, and password authentication

Updated Nov 29, 2025
Edit on GitHub

Authentication Module

The authentication module (sso.auth) handles all authentication flows including OAuth, device flow, token management, and password-based authentication.

OAuth Login URLs

Method: sso.auth.getLoginUrl()

Signature:

getLoginUrl(provider: OAuthProvider, params: LoginUrlParams): string

Description: Constructs the OAuth login URL for end-users. This does not perform the redirect; the consuming application should redirect the user’s browser to this URL.

Parameters:

Name Type Description
provider OAuthProvider The OAuth provider to use (‘github’, ‘google’, ‘microsoft’)
params LoginUrlParams Login parameters including org, service, and redirect_uri
params.org string Organization slug
params.service string Service slug
params.redirect_uri string (optional) Callback URL after authentication
params.user_code string (optional) Device flow user code to link browser session to device

Returns: string - The full URL to redirect the user to

Example:

const url = sso.auth.getLoginUrl('github', {
  org: 'acme-corp',
  service: 'main-app',
  redirect_uri: 'https://app.acme.com/callback'
});
window.location.href = url;

Related:


Method: sso.auth.getAdminLoginUrl()

Signature:

getAdminLoginUrl(provider: OAuthProvider, params?: AdminLoginUrlParams): string

Description: Constructs the OAuth login URL for platform/organization admins. This uses the platform’s dedicated OAuth credentials instead of tenant-specific credentials.

Parameters:

Name Type Description
provider OAuthProvider The OAuth provider to use (‘github’, ‘google’, ‘microsoft’)
params AdminLoginUrlParams (optional) Optional admin login parameters
params.org_slug string (optional) Organization slug to redirect to after login
params.user_code string (optional) Device flow user code for CLI/device authentication

Returns: string - The full URL to redirect the admin to

Example:

const url = sso.auth.getAdminLoginUrl('github', {
  org_slug: 'acme-corp'
});
window.location.href = url;

Related:


Device Flow (RFC 8628)

The device flow enables authentication for CLIs, mobile apps, and other devices with limited input capabilities.

Method: sso.auth.deviceCode.request()

Signature:

deviceCode.request(payload: DeviceCodeRequest): Promise<DeviceCodeResponse>

Description: Request a device code for CLI/device authentication. Returns a user code that the user must enter on a separate device.

Parameters:

Name Type Description
payload DeviceCodeRequest Device code request payload
payload.client_id string Service client ID
payload.org string Organization slug
payload.service string Service slug

Returns: Promise<DeviceCodeResponse> - Device code response with user code and verification URI

Response Fields:

Field Type Description
device_code string Code to use when polling for token
user_code string Human-friendly code for user to enter
verification_uri string URL where user should enter the code
expires_in number Seconds until codes expire
interval number Recommended polling interval in seconds

Example:

const response = await sso.auth.deviceCode.request({
  client_id: 'service-client-id',
  org: 'acme-corp',
  service: 'acme-cli'
});
console.log(`Visit ${response.verification_uri} and enter code: ${response.user_code}`);

Throws:

  • SsoApiError - When service/organization not found or invalid parameters

Related:


Method: sso.auth.deviceCode.verify()

Signature:

deviceCode.verify(userCode: string): Promise<DeviceVerifyResponse>

Description: Verify a user code and get the context (org_slug, service_slug) needed for the UI to initiate the appropriate OAuth flow. This is called by the web UI when a user enters their device code.

Parameters:

Name Type Description
userCode string The user-friendly code displayed on the device (e.g., “ABCD-1234”)

Returns: Promise<DeviceVerifyResponse> - Context with organization and service information

Response Fields:

Field Type Description
org_slug string Organization slug for this device code
service_slug string Service slug for this device code

Example:

const context = await sso.auth.deviceCode.verify('ABCD-1234');
// Use context.org_slug and context.service_slug to determine which OAuth flow to initiate
const loginUrl = sso.auth.getLoginUrl('github', {
  org: context.org_slug,
  service: context.service_slug,
  user_code: 'ABCD-1234'  // Pass user_code to link browser session to device
});
window.location.href = loginUrl;

Throws:

  • SsoApiError - When user code is invalid, expired, or already used

Related:


Method: sso.auth.deviceCode.exchangeToken()

Signature:

deviceCode.exchangeToken(payload: TokenRequest): Promise<TokenResponse>

Description: Exchange a device code for a JWT token. This should be polled by the device/CLI after displaying the user code. Continue polling until authorization is granted or the code expires.

Parameters:

Name Type Description
payload TokenRequest Token request payload
payload.grant_type string Must be ‘urn:ietf:params:oauth:grant-type:device_code’
payload.device_code string Device code from request() call
payload.client_id string Service client ID

Returns: Promise<TokenResponse> - Token response with JWT access token

Response Fields:

Field Type Description
access_token string JWT access token
token_type string Always “Bearer”
expires_in number Seconds until token expires

Example:

// Poll every 5 seconds
const interval = setInterval(async () => {
  try {
    const token = await sso.auth.deviceCode.exchangeToken({
      grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
      device_code: deviceCode,
      client_id: 'service-client-id'
    });
    clearInterval(interval);
    sso.setAuthToken(token.access_token);
    console.log('Authentication successful!');
  } catch (error) {
    if (error.errorCode === 'authorization_pending') {
      // Continue polling
      return;
    }
    // Other error - stop polling
    clearInterval(interval);
    throw error;
  }
}, 5000);

Throws:

  • SsoApiError -
    • authorization_pending - User hasn’t authorized yet (continue polling)
    • slow_down - Polling too frequently (increase interval)
    • expired_token - Device code has expired
    • access_denied - User denied authorization

Related:


Token Management

Method: sso.auth.logout()

Signature:

logout(): Promise<void>

Description: Logout the current user by revoking their JWT. Automatically clears the session and removes tokens from storage.

Parameters: None

Returns: Promise<void>

Example:

// Logout automatically clears the session
await sso.auth.logout();

// The SDK automatically:
// - Revokes token on the server
// - Clears the session
// - Removes tokens from localStorage
// - Triggers onAuthStateChange listeners

// Redirect to login page
window.location.href = '/login';

Throws:

  • SsoApiError - When user is not authenticated or token is invalid

Related:


Method: sso.auth.refreshToken()

Signature:

refreshToken(refreshToken: string): Promise<RefreshTokenResponse>

Description: Refresh an expired JWT access token using a refresh token. This implements token rotation - both the access token and refresh token will be renewed with each call for enhanced security. Note: The SDK automatically handles token refresh when it detects a 401 error, so you typically don’t need to call this method manually.

Parameters:

Name Type Description
refreshToken string The refresh token obtained during login

Returns: Promise<RefreshTokenResponse> - New access token and refresh token pair

Response Fields:

Field Type Description
access_token string New JWT access token
refresh_token string New refresh token (replaces old one)
token_type string Always “Bearer”
expires_in number Seconds until access token expires

Example:

try {
  const tokens = await sso.auth.refreshToken(storedRefreshToken);
  sso.setAuthToken(tokens.access_token);
  localStorage.setItem('sso_access_token', tokens.access_token);
  localStorage.setItem('sso_refresh_token', tokens.refresh_token);
} catch (error) {
  // Refresh failed - redirect to login
  window.location.href = '/login';
}

Throws:

  • SsoApiError - When refresh token is invalid, expired, or revoked

Related:


Method: sso.auth.getProviderToken()

Signature:

getProviderToken(provider: OAuthProvider): Promise<ProviderToken>

Description: Get a fresh provider access token for the authenticated user. This will automatically refresh the token if it’s expired. Use this to make API calls to external providers (GitHub, Google, Microsoft) on behalf of the user.

IMPORTANT: This method requires a service-context JWT (obtained through end-user OAuth flow). It will fail if called with a platform or organization-level admin token. Only tokens obtained via sso.auth.getLoginUrl() followed by OAuth callback or password login contain the necessary service context.

Parameters:

Name Type Description
provider OAuthProvider The OAuth provider (‘github’, ‘google’, ‘microsoft’)

Returns: Promise<ProviderToken> - Fresh provider token

Response Fields:

Field Type Description
access_token string OAuth access token for the provider
token_type string Token type (usually “Bearer”)
scope string Granted scopes
expires_at string (optional) ISO timestamp when token expires

Example:

const token = await sso.auth.getProviderToken('github');
// Use token.access_token to make GitHub API calls
const response = await fetch('https://api.github.com/user', {
  headers: {
    'Authorization': `Bearer ${token.access_token}`
  }
});

Throws:

  • SsoApiError - When user is not authenticated or doesn’t have linked identity for provider

Related:


Password Authentication

The platform supports native username/password authentication alongside OAuth providers.

Method: sso.auth.register()

Signature:

register(payload: RegisterRequest): Promise<RegisterResponse>

Description: Register a new user with email and password. After registration, the user will receive a verification email before they can login.

Parameters:

Name Type Description
payload RegisterRequest Registration details
payload.email string User’s email address
payload.password string User’s password (must meet security requirements)

Returns: Promise<RegisterResponse> - Registration confirmation message

Response Fields:

Field Type Description
message string Confirmation message
user_id string ID of created user

Example:

const response = await sso.auth.register({
  email: 'user@example.com',
  password: 'SecurePassword123!'
});
console.log(response.message); // "Registration successful. Please check your email to verify your account."

Throws:

  • SsoApiError -
    • When email is already registered
    • When password doesn’t meet requirements
    • When email format is invalid

Related:


Method: sso.auth.login()

Signature:

login(payload: LoginRequest): Promise<RefreshTokenResponse>

Description: Login with email and password. Automatically persists the session and configures the SDK client. Returns access token and refresh token on successful authentication. The user’s email must be verified before login is allowed.

Parameters:

Name Type Description
payload LoginRequest Login credentials
payload.email string User’s email address
payload.password string User’s password

Returns: Promise<RefreshTokenResponse> - Access token, refresh token, and expiration info

Response Fields:

Field Type Description
access_token string JWT access token (or pre-auth token if MFA enabled)
refresh_token string Refresh token (or empty if MFA required)
token_type string Always “Bearer”
expires_in number Seconds until token expires (300 if MFA required, otherwise normal expiry)

Example:

// Login automatically saves the session
const tokens = await sso.auth.login({
  email: 'user@example.com',
  password: 'SecurePassword123!'
});

// Check if MFA is required
if (tokens.expires_in === 300) {
  // This is a pre-auth token - user needs to provide MFA code
  // Session is NOT saved yet - waiting for MFA verification
  const mfaCode = prompt('Enter your 6-digit code from authenticator app');
  // MFA verification automatically saves the full session
  await sso.auth.verifyMfa(tokens.access_token, mfaCode);
} else {
  // Normal login without MFA - session already saved automatically
  console.log('Logged in successfully');
}

// The SDK now automatically:
// - Stores tokens in localStorage (or custom storage)
// - Injects tokens on all API requests
// - Refreshes expired tokens automatically

Throws:

  • SsoApiError -
    • When email/password is incorrect
    • When email is not verified
    • When account is disabled

Related:


Method: sso.auth.verifyMfa()

Signature:

verifyMfa(preauthToken: string, code: string, deviceCodeId?: string): Promise<MfaVerificationResponse>

Description: Verify MFA code and complete authentication. This method should be called after login when the user has MFA enabled. The login will return a pre-auth token with a short expiration (5 minutes). Exchange the pre-auth token and TOTP code for a full session.

Parameters:

Name Type Description
preauthToken string Pre-authentication token received from login
code string TOTP code from authenticator app or a backup code
deviceCodeId string (optional) Device code ID for device flow authentication

Returns: Promise<MfaVerificationResponse> - Full session tokens

Response Fields:

Field Type Description
access_token string JWT access token
refresh_token string Refresh token
token_type string Always “Bearer”
expires_in number Seconds until access token expires

Example:

// After login, if MFA is enabled:
const loginResponse = await sso.auth.login({
  email: 'user@example.com',
  password: 'password'
});

// Check if this is a pre-auth token (expires_in will be 300 seconds = 5 minutes)
if (loginResponse.expires_in === 300) {
  // User needs to provide MFA code
  const mfaCode = prompt('Enter your 6-digit code from authenticator app');
  const tokens = await sso.auth.verifyMfa(loginResponse.access_token, mfaCode);
  sso.setAuthToken(tokens.access_token);
  localStorage.setItem('sso_access_token', tokens.access_token);
  localStorage.setItem('sso_refresh_token', tokens.refresh_token);
}

Throws:

  • SsoApiError -
    • When pre-auth token is invalid or expired
    • When TOTP code is incorrect
    • When backup code is invalid or already used

Related:


Method: sso.auth.requestPasswordReset()

Signature:

requestPasswordReset(payload: ForgotPasswordRequest): Promise<ForgotPasswordResponse>

Description: Request a password reset for a user account. If the email exists, a reset link will be sent to the user. Returns success regardless of whether the email exists (to prevent email enumeration).

Parameters:

Name Type Description
payload ForgotPasswordRequest Password reset request
payload.email string User’s email address

Returns: Promise<ForgotPasswordResponse> - Confirmation message

Response Fields:

Field Type Description
message string Confirmation message

Example:

const response = await sso.auth.requestPasswordReset({
  email: 'user@example.com'
});
console.log(response.message); // "If an account exists with this email, a password reset link has been sent."

Throws:

  • SsoApiError - When email format is invalid

Related:


Method: sso.auth.resetPassword()

Signature:

resetPassword(payload: ResetPasswordRequest): Promise<ResetPasswordResponse>

Description: Reset a user’s password using a reset token from email. The token is obtained from the password reset email link.

Parameters:

Name Type Description
payload ResetPasswordRequest Reset password request
payload.token string Reset token from email
payload.new_password string New password (must meet security requirements)

Returns: Promise<ResetPasswordResponse> - Confirmation message

Response Fields:

Field Type Description
message string Confirmation message

Example:

const response = await sso.auth.resetPassword({
  token: 'reset-token-from-email',
  new_password: 'NewSecurePassword123!'
});
console.log(response.message); // "Password reset successfully"

Throws:

  • SsoApiError -
    • When token is invalid or expired
    • When new password doesn’t meet requirements

Related:


Passkeys (WebAuthn)

The passkeys module (sso.passkeys) provides FIDO2/WebAuthn authentication methods for passwordless login using biometrics or hardware security keys.

Method: sso.passkeys.isSupported()

Signature:

isSupported(): boolean

Description: Check if WebAuthn is supported in the current browser environment.

Parameters: None

Returns: boolean - True if WebAuthn is supported, false otherwise

Example:

if (sso.passkeys.isSupported()) {
  console.log('Passkeys are supported on this device');
} else {
  console.log('Passkeys not available - show alternative login methods');
}

Throws: None

Related:


Method: sso.passkeys.isPlatformAuthenticatorAvailable()

Signature:

isPlatformAuthenticatorAvailable(): Promise<boolean>

Description: Check if a platform authenticator (Touch ID, Face ID, Windows Hello) is available on the device. This does not detect external security keys.

Parameters: None

Returns: Promise<boolean> - True if platform authenticator is available

Example:

const hasPlatformAuth = await sso.passkeys.isPlatformAuthenticatorAvailable();
if (hasPlatformAuth) {
  console.log('Can use Touch ID / Face ID / Windows Hello');
}

Throws: None

Related:


Method: sso.passkeys.register()

Signature:

register(displayName?: string): Promise<string>

Description: Register a new passkey for the authenticated user. This method requires an active JWT session. The browser prompts the user to create a passkey using their device’s authenticator (Touch ID, Face ID, Windows Hello, or hardware security key).

Parameters:

Name Type Description
displayName string (optional) Display name for the passkey (e.g., “My MacBook Pro”)

Returns: Promise<string> - The registered passkey ID

Example:

try {
  const passkeyId = await sso.passkeys.register('My MacBook Pro');
  console.log('Passkey registered with ID:', passkeyId);
} catch (error) {
  console.error('Passkey registration failed:', error);
}

Throws:

  • Error - When WebAuthn is not supported in the browser
  • SsoApiError - When user is not authenticated or registration fails

Related:


Method: sso.passkeys.login()

Signature:

login(email: string): Promise<PasskeyAuthFinishResponse>

Description: Authenticate using a passkey and obtain a JWT token. The browser prompts the user to authenticate using their registered passkey.

Parameters:

Name Type Description
email string User’s email address

Returns: Promise<PasskeyAuthFinishResponse> - Authentication response with JWT token

Response Fields:

Field Type Description
token string JWT access token
user_id string Authenticated user’s ID

Example:

try {
  const result = await sso.passkeys.login('user@example.com');
  sso.setAuthToken(result.token);
  localStorage.setItem('sso_access_token', result.token);
  console.log('Logged in as:', result.user_id);
} catch (error) {
  console.error('Passkey login failed:', error);
}

Throws:

  • Error - When WebAuthn is not supported in the browser
  • SsoApiError - When user has no registered passkeys or authentication fails

Related:


The magic links module (sso.magicLinks) enables passwordless authentication via email links.

Method: sso.magicLinks.request()

Signature:

request(data: MagicLinkRequest): Promise<MagicLinkResponse>

Description: Request a magic link to be sent to the user’s email address. The email contains a one-time login link that authenticates the user when clicked.

Parameters:

Name Type Description
data MagicLinkRequest Magic link request payload
data.email string Email address to send the magic link to
data.orgSlug string (optional) Organization context for the login

Returns: Promise<MagicLinkResponse> - Confirmation message

Response Fields:

Field Type Description
message string Success confirmation message

Example:

const response = await sso.magicLinks.request({
  email: 'user@example.com',
  orgSlug: 'acme-corp'
});
console.log(response.message); // "Magic link sent to your email"

Throws:

  • SsoApiError - When email format is invalid or rate limit exceeded

Related:


Method: sso.magicLinks.verify()

Signature:

verify(token: string, redirectUri?: string): Promise<any>

Description: Verify a magic link token and complete authentication. This method exchanges the token for a JWT session. Use this when handling magic link verification via API call rather than browser redirect.

Parameters:

Name Type Description
token string The magic link token from the email
redirectUri string (optional) Optional redirect URI after successful verification

Returns: Promise<any> - Authentication response with tokens

Example:

// Extract token from URL query parameter
const urlParams = new URLSearchParams(window.location.search);
const token = urlParams.get('token');

if (token) {
  const auth = await sso.magicLinks.verify(token);
  sso.setAuthToken(auth.access_token);
  localStorage.setItem('sso_access_token', auth.access_token);
}

Throws:

  • SsoApiError - When token is invalid, expired, or already used

Related:


Method: sso.magicLinks.getVerificationUrl()

Signature:

getVerificationUrl(token: string, redirectUri?: string): string

Description: Construct the verification URL for a magic link token. This is typically used when you need to generate the URL that would be sent in the email.

Parameters:

Name Type Description
token string The magic link token
redirectUri string (optional) Optional redirect URI after successful verification

Returns: string - The verification URL path

Example:

const verifyUrl = sso.magicLinks.getVerificationUrl('token-abc123', 'https://app.acme.com/dashboard');
console.log('Verification URL:', verifyUrl);
// "/api/auth/magic-link/verify?token=token-abc123&redirect_uri=https://app.acme.com/dashboard"

Throws: None

Related:


Type Definitions

OAuthProvider

type OAuthProvider = 'github' | 'google' | 'microsoft';

LoginUrlParams

interface LoginUrlParams {
  org: string;
  service: string;
  redirect_uri?: string;
  user_code?: string;
}

AdminLoginUrlParams

interface AdminLoginUrlParams {
  org_slug?: string;
  user_code?: string;
}

DeviceCodeRequest

interface DeviceCodeRequest {
  client_id: string;
  org: string;
  service: string;
}

DeviceCodeResponse

interface DeviceCodeResponse {
  device_code: string;
  user_code: string;
  verification_uri: string;
  expires_in: number;
  interval: number;
}

DeviceVerifyResponse

interface DeviceVerifyResponse {
  org_slug: string;
  service_slug: string;
}

TokenRequest

interface TokenRequest {
  grant_type: 'urn:ietf:params:oauth:grant-type:device_code';
  device_code: string;
  client_id: string;
}

TokenResponse

interface TokenResponse {
  access_token: string;
  token_type: string;
  expires_in: number;
}

RefreshTokenResponse

interface RefreshTokenResponse {
  access_token: string;
  refresh_token: string;
  token_type: string;
  expires_in: number;
}

ProviderToken

interface ProviderToken {
  access_token: string;
  token_type: string;
  scope: string;
  expires_at?: string;
}

RegisterRequest

interface RegisterRequest {
  email: string;
  password: string;
}

RegisterResponse

interface RegisterResponse {
  message: string;
  user_id: string;
}

LoginRequest

interface LoginRequest {
  email: string;
  password: string;
}

ForgotPasswordRequest

interface ForgotPasswordRequest {
  email: string;
}

ForgotPasswordResponse

interface ForgotPasswordResponse {
  message: string;
}

ResetPasswordRequest

interface ResetPasswordRequest {
  token: string;
  new_password: string;
}

ResetPasswordResponse

interface ResetPasswordResponse {
  message: string;
}

MfaVerificationResponse

interface MfaVerificationResponse {
  access_token: string;
  refresh_token: string;
  token_type: string;
  expires_in: number;
}