Authentication Methods
OAuth 2.0
Industry-standard OAuth flows for Google and GitHub
Magic Links
Passwordless email-based authentication
Device Code Flow
CLI and VS Code authentication via browser
Okta SSO
Enterprise SAML/OIDC authentication
OAuth 2.0 Providers
Loom implements OAuth 2.0 / OpenID Connect flows for third-party authentication providers.Google OAuth
Configure OAuth App
Set up a Google OAuth 2.0 application in the Google Cloud Console:
OAuth Flow
The Google OAuth flow uses OpenID Connect with the following scopes:
openid- Required for OIDCemail- Access to user’s email addressprofile- Access to user’s display name and avatar
- State parameter for CSRF protection (random, unguessable)
- Nonce parameter for replay protection (validated in ID token)
- ID token signature verification using Google’s public keys
The ID token approach is preferred over the
/userinfo endpoint because it avoids an extra API call and provides cryptographically verifiable claims.GitHub OAuth
GitHub OAuth provides seamless authentication for developers already using GitHub.user:email- Read user’s email addresses (including private)read:user- Read user profile information
Magic Links
Magic links provide passwordless authentication via email. Users receive a unique, time-limited link that logs them in when clicked.Security Properties
Single-Use
Each link can only be used once. After verification, the link is marked as used and cannot be reused.
Short-Lived
Links expire after 10 minutes to minimize the window for token interception.
Cryptographically Secure
Tokens are generated using 32 bytes of cryptographically secure random data (256 bits of entropy).
Argon2id Hashing
Tokens are hashed with Argon2id before storage, protecting against database leaks.
Flow Overview
Implementation Details
Argon2id provides stronger protection
Argon2id provides stronger protection
While 32-byte tokens have 256 bits of entropy (making brute-force infeasible), Argon2id provides defense-in-depth:
- Brute-force resistance - Memory-hard design makes GPU/ASIC attacks significantly more expensive
- Future-proof - Additional protection if token generation is ever weakened
- Industry best practice - OWASP recommends Argon2id for password and token hashing
- Salt included - Each hash includes a unique salt, preventing rainbow table attacks
When a new magic link is requested, any previous links for that email are invalidated. This prevents accumulation of valid tokens and reduces the attack surface.
Device Code Flow
Device code flow enables authentication on headless or input-constrained devices (CLIs, VS Code) by offloading the authentication to a browser.Flow Diagram
Two Codes: Why?
The flow uses two distinct codes for security and usability:device_code (UUID)
device_code (UUID)
Purpose: Internal identifier used by the CLI for polling.
- Cryptographically random UUID (128 bits of entropy)
- Hard to guess, making brute-force polling infeasible
- Never displayed to users
- Only travels in CLI ↔ Server communication
user_code (123-456-789)
user_code (123-456-789)
Purpose: Human-readable code displayed to the user.
- Format: 9 digits grouped by dashes (
XXX-XXX-XXX) - Easy to read aloud and type on any keyboard
- 10^9 possibilities = ~30 bits of entropy
- Users enter this in the browser to link authentication
Security Properties
Time-Limited
Time-Limited
Device codes expire after 10 minutes to limit the attack window:
Rate-Limited Polling
Rate-Limited Polling
Polling is rate-limited to 1 request per second to prevent abuse:The server may return
slow_down if the client polls too frequently.Single-Use Codes
Single-Use Codes
User codes are single-use and bound to a specific device code. Once a user completes authentication:
CSRF-Immune
CSRF-Immune
The flow is immune to CSRF attacks because it doesn’t rely on browser cookies. The CLI holds the
device_code secret, and the browser only knows the user_code.State Machine
- A code starts as
Pending - It transitions to either
Completed(user authenticated) orExpired(timeout) - Once in a terminal state, the status never changes
Enterprise SSO (Okta)
For enterprise deployments, Loom supports Okta SAML/OIDC authentication.The Okta integration uses the same OAuth 2.0 patterns as Google and GitHub, with Okta-specific discovery endpoints and token validation.
Security Best Practices
Secret Protection
All secrets (API keys, client secrets, tokens) are wrapped in
SecretString types that auto-redact in logs, Debug output, and serialization.State Validation
Always validate the
state parameter in OAuth callbacks to prevent CSRF attacks. Use cryptographically random values.Nonce Validation
For OIDC flows, validate the
nonce claim in ID tokens to prevent replay attacks.Email Verification
Only trust verified email addresses from OAuth providers. Unverified emails can be set by anyone.
API Reference
Device Code Flow Endpoints
Magic Link Flow
See loom-server/src/routes/auth/ for complete route implementations.