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 expiredaccess_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 browserSsoApiError- 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 |
|---|---|---|
| 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 browserSsoApiError- When user has no registered passkeys or authentication fails
Related:
Magic Links
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;
}