Developer Docs

Auth & Identity โ€” Integration Guide

Overview

The auth service (Rust) is the single source of truth for platform identity. It handles user registration, session management, multi-factor authentication, corporate SSO (SAML 2.0), and SCIM provisioning token lifecycle โ€” powering both consumer and enterprise identity flows.

Port: 3008 ยท Framework: Axum + async-graphql ยท Database: PostgreSQL + Redis


Authentication Methods

The auth service implements a passwordless-first identity strategy. Passwords are intentionally excluded by design.

Method Type Use Case
OAuth2 Primary Google, Apple, X, Facebook login
Passkeys (WebAuthn) Primary Biometric/hardware key โ€” phishing-resistant
Email OTP Fallback 6-digit code via Resend โ€” accessible on any device
SAML 2.0 SSO Enterprise Corporate IdP login (Okta, Azure AD, Google Workspace)
Native Mobile Mobile OAuth token exchange for React Native apps
Guest Tokens Ephemeral Scoped, short-lived access (QR codes, shared links)

For detailed MFA (TOTP, SMS, backup codes) and Passkey integration, see MFA & Passkeys.


SAML 2.0 โ€” Enterprise SSO

The auth service acts as a SAML Service Provider (SP), receiving assertions from corporate IdPs to authenticate Organization members.

Configuration

Organization admins configure SAML via GraphQL:

mutation ConfigureSaml($orgId: ID!, $input: ConfigureSamlInput!) {
	configureSaml(orgId: $orgId, input: $input) {
		orgId
		entityId
		ssoUrl
		certificate
		attributeMapping {
			email
			firstName
			lastName
		}
	}
}

SAML Endpoints

Method Path Description
POST /auth/saml/:org_id/acs Assertion Consumer Service โ€” receives IdP assertion, creates session
GET /auth/saml/:org_id/metadata SP Metadata XML for IdP configuration

Login Flow

  1. Visitor clicks "Login with SSO" โ†’ redirected to IdP
  2. IdP authenticates โ†’ posts SAML assertion to /auth/saml/:org_id/acs
  3. Auth service parses assertion โ†’ finds or creates user by email
  4. Session + refresh tokens issued โ†’ Visitor redirected with active cookies
  5. AuthMethod::Saml audit event logged

GraphQL API

# View config (certificate masked)
query {
	samlConfig(orgId: "org-01") {
		entityId
		ssoUrl
		certificate
		attributeMapping {
			email
			firstName
			lastName
		}
	}
}

# Update config
mutation {
	updateSamlConfig(orgId: "org-01", input: { ssoUrl: "https://new-idp.com/sso" }) {
		orgId
		ssoUrl
	}
}

# Delete config (disables SSO)
mutation {
	deleteSamlConfig(orgId: "org-01")
}

# Test connectivity
mutation {
	testSamlConfig(orgId: "org-01") {
		success
		message
	}
}

For the full feature overview including SCIM provisioning, see Corporate Identity (SAML & SCIM).


SCIM Token Management

The auth service manages SCIM bearer tokens that the dedicated SCIM service uses for authentication. Tokens are stored as SHA-256 hashes โ€” the raw value is returned once on generation and never persisted.

# Generate token (raw value shown ONCE)
mutation {
	generateScimToken(orgId: "org-01", label: "Okta SCIM") {
		token # โ† copy immediately
		id
		label
	}
}

# List active tokens (no raw values)
query {
	scimTokens(orgId: "org-01") {
		id
		label
		lastUsedAt
		createdAt
	}
}

# Revoke token (immediate)
mutation {
	revokeScimToken(orgId: "org-01", tokenId: "token-id")
}

Identity Checks (REST)

Before attempting a guest lookup or signup, use these REST endpoints to check if an account already exists.

Method Path Description
GET /auth/email/check?email=user@example.com Check email existence
GET /auth/phone/check?phone=+1234567890 Check phone existence

Response:

{
	"exists": true,
	"userId": "uuid-v4-identifier"
}

Session Management

Dual-Token Strategy

Token Cookie TTL Purpose
session_token HttpOnly, Lax 15 min Short-lived access token
refresh_token HttpOnly, Strict 30 days Long-lived rotation token

Key Endpoints

Method Path Description
POST /auth/refresh Rotate session + refresh tokens
POST /auth/logout Clear session and revoke refresh token
POST /auth/mobile/token Exchange OAuth token for JSON session (mobile)
POST /auth/mobile/refresh Refresh via JSON body (mobile)
POST /auth/mobile/logout Revoke via Bearer header (mobile)

GraphQL API

Queries

# Current user profile
query {
	me {
		id
		username
		email
		phone
		emailVerified
		createdAt
	}
}

# Session status
query {
	mySession {
		isAuthenticated
		userId
		deviceId
		hasRefreshToken
	}
}

# Device list
query {
	myDevices {
		id
		deviceName
		deviceType
		trusted
		isCurrent
		lastSeenAt
	}
}

# Security events
query {
	mySecurityEvents(limit: 20) {
		eventType
		severity
		description
		ipAddress
		createdAt
	}
}

# MFA status
query {
	mfaStatus {
		totpEnabled
		smsEnabled
		backupCodesRemaining
	}
}

# SAML config (requires MANAGE_SSO)
query {
	samlConfig(orgId: "org-01") {
		entityId
		ssoUrl
		certificate
	}
}

# SCIM tokens (requires MANAGE_SSO)
query {
	scimTokens(orgId: "org-01") {
		id
		label
		lastUsedAt
	}
}

Mutations

# Device management
mutation { trustDevice(deviceId: "...") { id trusted } }
mutation { untrustDevice(deviceId: "...") { id trusted } }
mutation { renameDevice(deviceId: "...", name: "Work Laptop") { id deviceName } }
mutation { revokeDevice(deviceId: "...") }

# WebSocket token (for uChat)
mutation { issueWsToken { token expiresIn } }

# Guest tokens
mutation { generateGuestToken(input: { scope: "malet:123" }) { token expiresAt } }
mutation { convertGuestToUser(guestTokenId: "...") { userId } }

# SAML configuration (requires MANAGE_SSO)
mutation { configureSaml(orgId: "...", input: { ... }) { orgId entityId ssoUrl } }
mutation { deleteSamlConfig(orgId: "...") }
mutation { testSamlConfig(orgId: "...") { success message } }

# SCIM tokens (requires MANAGE_SSO)
mutation { generateScimToken(orgId: "...", label: "Okta") { token id label } }
mutation { revokeScimToken(orgId: "...", tokenId: "...") }

MFA (Multi-Factor Authentication)

The auth service supports TOTP (authenticator app), SMS OTP, and backup codes as second factors. MFA is enforced across all login methods: email OTP, OAuth, passkeys, mobile, and SAML.

Endpoint Description
POST /auth/mfa/totp/enroll Start TOTP enrollment (returns secret + QR URI)
POST /auth/mfa/totp/confirm Verify code to activate TOTP
POST /auth/mfa/sms/enroll Start SMS MFA enrollment
POST /auth/mfa/sms/confirm Verify SMS code to activate
POST /auth/mfa/disable Disable MFA (requires valid code)
POST /auth/mfa/verify Verify MFA challenge during login
POST /auth/mfa/backup Use backup code during login
POST /auth/mfa/backup/regenerate Generate new backup codes

See MFA & Passkeys for the full integration guide with browser-side code examples.


Internal Workflow: Guest Redirection

When a user requests guest order access (via murchases), the system performs the following checks:

  1. Identity Check: murchases calls auth via the REST API above.
  2. Fail-Fast: If an account exists for the provided email/phone, the system prompts for Login instead of sending a Guest OTP.
  3. OTP Dispatch: If no account exists, a 6-digit code is sent via the alerts subgraph.

Database Schema

Table Description
users Core identity (email, phone, display_name, totp_secret)
oauth_accounts OAuth provider links (Google, Apple, X, Facebook)
passkeys WebAuthn credentials (public keys, sign counts)
email_otps Temporary codes for passwordless login
devices Known user devices/browsers (fingerprint, IP)
auth_events Security audit log (24 event types, 3 severity levels)
saml_configs Per-org SAML SP configuration (entity ID, SSO URL, certificate)
scim_tokens Per-org SCIM bearer token hashes (SHA-256, never plaintext)

File Reference

File Purpose
apps/auth/src/main.rs Server entry โ€” route registration, middleware
apps/auth/src/services/auth.rs Core auth logic (OAuth, sessions, guest tokens)
apps/auth/src/services/saml.rs SAML assertion parsing + SCIM token management
apps/auth/src/services/mfa.rs TOTP + SMS MFA + backup codes
apps/auth/src/services/passkey.rs WebAuthn ceremony logic
apps/auth/src/routes/saml.rs SAML ACS + SP metadata REST endpoints
apps/auth/src/routes/mfa.rs MFA REST endpoints
apps/auth/src/routes/phone.rs Phone identity check
apps/auth/src/graphql/mutation.rs GraphQL mutations (SAML, SCIM, MFA, devices)
apps/auth/src/graphql/query.rs GraphQL queries (me, samlConfig, scimTokens)

Testing

cd apps/auth && cargo test
Suite Tests
Session management 8
Device fingerprinting 6
SAML assertion parsing 6
SAML model serialization 4
SCIM token hashing 6
MFA enrollment/verify 10
Guest tokens 4
Audit events 6

Environment Variables

Variable Description
DATABASE_URL PostgreSQL connection string
REDIS_URL Redis connection string for session caching
AUTH_SERVICE_PORT HTTP server port
SESSION_SECRET Secret key for signing session cookies
COOKIE_MAX_AGE Maximum age for session cookies (in seconds)
GOOGLE_CLIENT_ID OAuth2 Client ID for Google login
GOOGLE_CLIENT_SECRET OAuth2 Client Secret for Google login
GOOGLE_REDIRECT_URI OAuth2 Redirect URI for Google login
WEBAUTHN_RP_ID Relying Party ID for WebAuthn (Passkeys)
WEBAUTHN_RP_NAME Relying Party Name for WebAuthn
WEBAUTHN_ORIGIN Origin URL for WebAuthn verification
RESEND_API_KEY API key for Resend email delivery
FROM_EMAIL Sender email address for OTPs