Authentication Concepts

Core authentication concepts including JWT structure, RS256 signing, dual authentication flows, and Bring Your Own OAuth (BYOO) integration.

Updated Dec 16, 2025
Edit on GitHub
authentication jwt oauth2 byoo

Authentication Concepts

This guide explains the core authentication concepts and patterns used in the AuthOS API.

JWT-Based Authentication

AuthOS uses JWT (JSON Web Tokens) for stateless authentication with server-side session tracking for revocation support.

JWT Signing Algorithm

All JWTs are signed using RS256 (RSA with SHA-256), an asymmetric signing algorithm. This means:

  • The API signs tokens using a private RSA key
  • Your backend can verify tokens using the public key from the JWKS endpoint
  • No shared secrets are required for token validation

JWT Structure

Every JWT issued by the platform contains these claims:

{
  "sub": "user_id",
  "email": "user@example.com",
  "is_platform_owner": false,
  "org": "organization-slug",    // Optional: Present in Org and Service JWTs
  "service": "service-slug",     // Optional: Present only in Service JWTs
  "plan": "premium",             // Optional: User's subscription plan
  "features": ["feature1"],      // Optional: Enabled features
  "exp": 1672531199,             // Expiration timestamp
  "iat": 1672444800,             // Issued at timestamp
  "kid": "sso-key-2025-01-01"    // Key ID for key rotation
}

JWT Types

The platform issues three conceptual types of JWTs based on the authentication context:

1. Platform Owner JWT

Used by super-admins for platform-wide administration.

{
  "sub": "user_id",
  "email": "admin@platform.com",
  "is_platform_owner": true,
  "org": null,
  "service": null,
  "exp": 1672531199,
  "iat": 1672444800
}

Usage: Accessing /api/platform/* endpoints for system administration.

2. Organization Management JWT

Used by organization owners and admins for managing their organization.

{
  "sub": "user_id",
  "email": "admin@company.com",
  "is_platform_owner": false,
  "org": "acme-corp",
  "service": null,
  "exp": 1672531199,
  "iat": 1672444800
}

Usage: Accessing /api/organizations/{org_slug}/* endpoints for organization management.

3. End-User Service JWT

Used by end-users within a specific application/service.

{
  "sub": "user_id",
  "email": "user@example.com",
  "is_platform_owner": false,
  "org": "acme-corp",
  "service": "main-app",
  "plan": "premium",
  "features": ["analytics", "api-access"],
  "exp": 1672531199,
  "iat": 1672444800
}

Usage:

  • Passed to your application’s redirect_uri for user sessions
  • Accessing user-centric endpoints like /api/user and /api/provider-token/:provider

Dual Authentication Flows

The platform features a dual-architecture authentication system that separates administrative access from end-user authentication.

Flow A: Platform & Organization Admin Login

Purpose: Administrative access to the platform or organization dashboards.

Endpoints: /auth/admin/:provider

OAuth Credentials: Uses the platform’s dedicated OAuth credentials configured in the API’s environment variables.

Token Type: Returns either a Platform Owner JWT or Organization Management JWT.

Process:

  1. User clicks “Login as Admin”
  2. Redirect to /auth/admin/github (or other provider)
  3. User authorizes via platform’s OAuth app
  4. User receives admin-level JWT
  5. Access platform/organization management features

Flow B: End-User Login (BYOO)

Purpose: End-users authenticate to access organization services.

Endpoints: /auth/:provider

OAuth Credentials: Dynamically selects between:

  • Organization’s custom OAuth app (if configured via BYOO)
  • Platform’s default OAuth app (fallback)

Token Type: Returns End-User Service JWT.

Process:

  1. User clicks “Login” in your app
  2. Redirect to /auth/github?org=acme-corp&service=main-app&redirect_uri=...
  3. User authorizes via organization’s or platform’s OAuth app
  4. User is redirected to your redirect_uri with tokens
  5. Your app uses the Service JWT for authentication

Flow C: Password Authentication

Purpose: Traditional username/password authentication without OAuth, supporting both platform-level and organization-scoped logins.

Endpoints: /api/auth/register, /api/auth/login, /api/auth/forgot-password, /api/auth/reset-password

Features:

  • User self-registration with email verification
  • Automatic invitation acceptance on registration
  • Secure password reset workflows
  • Argon2 password hashing
  • Organization-specific SMTP for transactional emails
  • Organization management login via org_slug parameter

Process:

# Registration
POST /api/auth/register
{
  "email": "user@example.com",
  "password": "SecurePass123!",
  "org_slug": "acme-corp"  // Optional: use org-specific SMTP
}

# Login (Platform Level)
POST /api/auth/login
{
  "email": "user@example.com",
  "password": "SecurePass123!"
}

# Login (Organization Management Context)
POST /api/auth/login
{
  "email": "admin@company.com",
  "password": "SecurePass123!",
  "org_slug": "acme-corp"  // Returns Organization Management JWT
}

# Response
{
  "access_token": "eyJhbGc...",
  "refresh_token": "eyJhbGc...",
  "token_type": "Bearer",
  "expires_in": 900
}

Organization Context Login: When org_slug is provided during login, the API:

  1. Verifies the user is a member of the specified organization
  2. Returns an Organization Management JWT (similar to admin OAuth flow)
  3. Allows access to /api/organizations/{org_slug}/* endpoints

This enables organization owners, admins, and members to manage their organization using password authentication instead of OAuth.

Flow D: Device Authorization (RFC 8628)

Purpose: Secure authentication for CLIs, smart devices, and headless applications.

Standards: Implements RFC 8628 Device Authorization Grant.

Process:

  1. Device requests codes:

    POST /auth/device/code
    {
      "client_id": "cli-app",
      "org": "acme-corp",
      "service": "acme-cli"
    }
    

    Response:

    {
      "device_code": "ABC123",
      "user_code": "WXYZ-1234",
      "verification_uri": "https://sso.example.com/activate",
      "expires_in": 600,
      "interval": 5
    }
    
  2. Device displays instructions:

    Visit: https://sso.example.com/activate
    Enter code: WXYZ-1234
    
  3. User visits verification URI and enters code. The web app:

    • Calls POST /auth/device/verify with the user_code
    • Gets context (org, service)
    • Redirects user to appropriate login flow with user_code parameter
  4. Device polls for token:

    POST /auth/token
    {
      "grant_type": "urn:ietf:params:oauth:grant-type:device_code",
      "device_code": "ABC123"
    }
    

    Eventually returns tokens when authorized.

Flow E: Token Refresh

Purpose: Renew expired access tokens without re-authentication.

Security: Uses refresh token rotation for enhanced security.

Process:

POST /api/auth/refresh
{
  "refresh_token": "current-refresh-token"
}

Response:

{
  "access_token": "new-access-token",
  "refresh_token": "new-refresh-token",  // Rotated for security
  "expires_in": 900
}

Important Notes:

  • Old refresh token is immediately revoked
  • Always store the new refresh token
  • Refresh tokens expire after 30 days of inactivity

Flow F: Passkey Authentication (WebAuthn)

Purpose: Passwordless authentication using FIDO2/WebAuthn hardware security keys or platform authenticators (Face ID, Touch ID, Windows Hello).

Standards: Implements W3C WebAuthn specification.

Security: Phishing-resistant, biometric-secured, public-key cryptography-based authentication.

Process:

  1. Registration (requires authenticated session):

    # Start passkey registration
    POST /auth/passkeys/register/start
    Authorization: Bearer {access_token}
    {
      "name": "My Security Key"  // Optional
    }
    

    Response:

    {
      "challenge_id": "challenge-uuid",
      "options": {
        "challenge": "base64-challenge",
        "rp": { "name": "AuthOS", "id": "sso.example.com" },
        "user": {
          "id": "user-id",
          "name": "user@example.com",
          "displayName": "user@example.com"
        },
        "pubKeyCredParams": [...],
        "authenticatorSelection": {...}
      }
    }
    
    # Complete passkey registration
    POST /auth/passkeys/register/finish
    Authorization: Bearer {access_token}
    {
      "challenge_id": "challenge-uuid",
      "credential": {
        "id": "credential-id",
        "rawId": "base64-raw-id",
        "response": {...},
        "type": "public-key"
      }
    }
    
  2. Authentication (passwordless login):

    # Start passkey authentication
    POST /auth/passkeys/authenticate/start
    {
      "email": "user@example.com"
    }
    

    Response:

    {
      "challenge_id": "challenge-uuid",
      "options": {
        "challenge": "base64-challenge",
        "rpId": "sso.example.com",
        "allowCredentials": [...]
      }
    }
    
    # Complete passkey authentication
    POST /auth/passkeys/authenticate/finish
    {
      "challenge_id": "challenge-uuid",
      "credential": {
        "id": "credential-id",
        "rawId": "base64-raw-id",
        "response": {...},
        "type": "public-key"
      }
    }
    

    Response:

    {
      "token": "jwt-access-token",
      "user_id": "user-id",
      "device_trust_token": "device-trust-token"  // Optional
    }
    

Features:

  • Phishing-Resistant: Origin-bound credentials prevent phishing attacks
  • Biometric Security: Leverages platform biometrics (Face ID, Touch ID)
  • Hardware Keys: Supports YubiKey, Google Titan, and other FIDO2 devices
  • Counter Tracking: Detects cloned authenticators via counter validation
  • Risk Assessment: Integrated with Risk Engine for additional security

Purpose: Passwordless authentication via email link, ideal for simplified onboarding.

Security: One-time use tokens with short expiration (15 minutes).

Process:

  1. Request magic link:

    POST /api/auth/magic-link/request
    {
      "email": "user@example.com",
      "org_slug": "acme-corp"  // Optional
    }
    

    Response (always returns success to avoid email enumeration):

    {
      "message": "If the email exists, a magic link has been sent."
    }
    
  2. User clicks email link with token parameter:

    https://sso.example.com/api/auth/magic-link/verify?token=magic-token-uuid
    
  3. Verify and authenticate:

    GET /api/auth/magic-link/verify?token=magic-token-uuid
    

    Response:

    {
      "access_token": "jwt-access-token",
      "refresh_token": "refresh-token",
      "expires_in": 900
    }
    

    Or if risk assessment requires MFA:

    {
      "requires_mfa": true,
      "preauth_token": "preauth-token",
      "message": "Additional verification required"
    }
    

Features:

  • One-Time Use: Tokens immediately deleted after successful verification
  • Time-Limited: 15-minute expiration window
  • Email Enumeration Protection: Always returns generic success message
  • Device Trust: Establishes trusted device cookie on success
  • Risk Assessment: Integrated with Risk Engine for fraud detection

Bring Your Own OAuth (BYOO)

BYOO allows tenant organizations to use their own OAuth2 applications, providing a white-labeled authentication experience for their end-users.

How BYOO Works

  1. Organization Setup:

    • Organization admin creates OAuth app with GitHub/Google/Microsoft
    • Admin configures OAuth credentials in AuthOS via:
      POST /api/organizations/acme-corp/oauth-credentials/github
      {
        "client_id": "org-github-client-id",
        "client_secret": "org-github-secret"
      }
      
  2. Credential Storage:

    • OAuth secrets are encrypted at rest using AES-GCM
    • Only decrypted during authentication flows
    • Never returned in API responses
  3. Dynamic Selection:

    • When user initiates login to a service, API checks for organization’s OAuth credentials
    • If found, uses organization’s OAuth app
    • If not found, falls back to platform’s default OAuth app
  4. End-User Experience:

    • Users see organization’s OAuth app name during authorization
    • Complete white-labeling of the authentication experience

Supported Providers

  • GitHub: Requires client_id and client_secret
  • Google: Requires client_id and client_secret
  • Microsoft: Requires client_id and client_secret

Security Considerations

  • Secrets are encrypted at rest with AES-GCM encryption
  • Each organization’s credentials are isolated
  • Credentials are only accessible to organization owners and admins
  • Client secrets are never returned via API (write-only)

Session Management

Session Lifecycle

  1. Creation: Session created on successful authentication
  2. Usage: Access token valid for 15 minutes
  3. Refresh: Use refresh token to get new access token (up to 30 days)
  4. Revocation: Sessions can be revoked via logout or admin action

Session Tracking

The API maintains a session table for:

  • JWT revocation support (logout functionality)
  • Security monitoring
  • Admin-initiated session termination
  • Analytics and audit trails

Logout

POST /api/auth/logout
Authorization: Bearer {access_token}

This invalidates the current session and prevents further use of the access token.

Multi-Factor Authentication (MFA)

The platform supports TOTP-based (Time-based One-Time Password) MFA for enhanced security.

MFA Features

  • TOTP secret encrypted at rest
  • QR code generation for authenticator apps
  • Backup recovery codes (encrypted)
  • Admin management capabilities
  • Per-user MFA enrollment

MFA Flow

  1. Setup: User generates TOTP secret via /api/user/mfa/setup
  2. Verification: User verifies with code via /api/user/mfa/verify
  3. Login: After password auth, user must provide TOTP code
  4. Recovery: Backup codes can be used if device is lost

See User Management API Reference for MFA endpoint details.

Risk Engine & Adaptive Authentication

The platform includes a sophisticated Risk Engine that evaluates login attempts in real-time to detect and prevent fraudulent access. Risk assessments run automatically during all authentication flows (password, OAuth, passkeys, magic links).

Risk Scoring Factors

The Risk Engine calculates a risk score (0-100) based on multiple signals:

1. Geographic Analysis (GeoIP)

  • Anomalous Location: Detects logins from countries/cities the user has never accessed from before (+15 points)
  • Impossible Travel: Identifies physically impossible location changes based on time elapsed (+25 points)
  • Database: Uses MaxMind GeoLite2-City database (optional, gracefully disabled if unavailable)

2. Velocity Detection

  • Rapid Login Attempts: Multiple login attempts from the same IP within short timeframes
  • Account Enumeration: Pattern detection for credential stuffing attacks
  • Time-Based Analysis: Evaluates login frequency per user, IP, and user-agent

3. Device Trust

  • New Device Detection: Flags logins from previously unseen devices (+10 points)
  • Device Fingerprinting: Tracks devices via secure HMAC-signed cookies
  • Trust Establishment: Successful logins establish 90-day device trust
  • Token Storage: Device tokens stored with SHA256 hashing

4. User Agent Analysis

  • Known Patterns: Detects suspicious user agents (bots, scrapers)
  • Consistency: Flags sudden changes in browser/OS patterns

Risk Actions

Based on the calculated risk score, the engine takes one of four actions:

Action Score Range Behavior
Allow 0-40 Login succeeds, device trust established
LogOnly 41-60 Login succeeds, event logged for analysis
ChallengeMFA 61-80 Requires additional MFA verification
Block 81-100 Login denied, security alert triggered

Risk Assessment Flow

  1. Login Attempt: User submits credentials (any authentication method)
  2. Context Collection: Platform gathers IP address, user agent, device cookie, location
  3. Risk Evaluation: Engine calculates score based on all available signals
  4. Rule Application: Custom organization rules can override default thresholds
  5. Action Enforcement: Platform enforces the determined action
  6. Event Logging: All assessments logged to login_events table with risk data

Organization Risk Settings

Organizations can customize risk engine behavior per their security requirements:

PUT /api/organizations/:org_slug/risk-settings
{
  "enabled": true,
  "mode": "enforce",  // "enforce" or "monitor"
  "block_threshold": 80,
  "mfa_threshold": 60,
  "geoip_enabled": true,
  "velocity_enabled": true,
  "device_trust_enabled": true
}

Modes:

  • Enforce: Risk engine actions are applied (default)
  • Monitor: All logins succeed, but risk scores are logged for analysis

Device Trust

Successful low-risk logins establish device trust:

Set-Cookie: device_token={signed-token}; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=7776000

Features:

  • 90-Day Trust: Device tokens valid for 90 days
  • HMAC-Signed: Tokens cryptographically signed to prevent tampering
  • Database Tracking: All trusted devices stored with metadata
  • User Management: Users can revoke device trust via account settings

Risk Event Logging

All authentication attempts with risk assessments are logged:

CREATE TABLE login_events (
  id TEXT PRIMARY KEY,
  user_id TEXT NOT NULL,
  service_id TEXT,
  auth_method TEXT NOT NULL,  -- "password", "oauth", "passkey", "magic_link"
  ip_address TEXT,
  user_agent TEXT,
  risk_score INTEGER,          -- 0-100
  risk_factors TEXT,           -- JSON array: ["new_device", "anomalous_location"]
  geo_country TEXT,
  geo_city TEXT,
  geo_lat REAL,
  geo_long REAL,
  created_at TEXT NOT NULL
);

Integration with Authentication Flows

Risk Engine automatically integrates with all authentication methods:

  • Password Login: Risk score calculated before issuing JWT
  • OAuth Callback: Risk assessment runs after provider authorization
  • Passkey Authentication: Risk evaluation after WebAuthn verification
  • Magic Link: Risk check when user clicks email link
  • Device Flow: Risk assessment when device is authorized

Example: High-Risk Login

{
  "risk_assessment": {
    "score": 75,
    "action": "challenge_mfa",
    "factors": [
      "new_device",
      "anomalous_location",
      "impossible_travel"
    ],
    "location": {
      "country": "CN",
      "city": "Shanghai",
      "latitude": 31.2304,
      "longitude": 121.4737
    }
  },
  "response": {
    "requires_mfa": true,
    "preauth_token": "eyJhbGc...",
    "message": "Additional verification required due to unusual login location"
  }
}

Security Best Practices

  1. Enable GeoIP: Download MaxMind GeoLite2 database for geographic analysis
  2. Monitor Logs: Review login_events table for suspicious patterns
  3. Customize Thresholds: Adjust risk thresholds per organization security posture
  4. Device Trust: Educate users about trusted device management
  5. MFA Enforcement: Require MFA for high-value accounts regardless of risk
  6. Alert Integration: Connect risk events to SIEM platforms via webhooks

Environment Configuration

# Risk Engine Settings
GEOIP_DATABASE_PATH=data/GeoLite2-City.mmdb
GEOIP_DISABLED=false
DEVICE_TRUST_SECRET=your-32-byte-secret-key

# Disable GeoIP if database unavailable
GEOIP_DISABLED=true

Next Steps