Magical Auth Architecture
Understanding the technical architecture behind Magical Auth.
System Components
Magical Auth involves multiple parties working together to securely verify phone numbers without SMS:
User's Device
Mobile / Desktop Browser
Your Client App
Web / Mobile Application
Your Backend Server
Application Server
Glide Magical Auth
Identity Verification Service
Mobile Carrier Networks
Cellular Network Providers
Component Details
User's Device
The physical device containing the SIM card. This is where the cryptographic proof of phone ownership originates.
| Aspect | Description |
|---|---|
| What it does | Contains the SIM card and provides cryptographic proof of phone number ownership |
| Key capability | Accesses SIM credentials via OS-level APIs (Digital Credentials API on Android, App Clips on iOS) |
| Data provided | Encrypted credential token signed by the carrier |
Your Client App
Your web or mobile application that initiates the authentication flow.
| Aspect | Description |
|---|---|
| What it does | Integrates Glide's Web Client SDK to trigger the secure prompt |
| Key responsibility | Calls prepare() and invokeSecurePrompt() |
| Never handles | Raw phone numbers or carrier credentials directly |
Your Backend Server
Your server-side application that communicates with Glide's API.
| Aspect | Description |
|---|---|
| What it does | Holds your client credentials, calls Glide's prepare/process endpoints |
| Key responsibility | Receives verified phone numbers and makes business decisions |
| Provides | consent_data for privacy compliance, client_info for strategy selection |
Glide Magical Auth Server
Glide's authentication aggregator that orchestrates the verification flow.
| Aspect | Description |
|---|---|
| What it does | Selects optimal authentication strategy, manages sessions, validates credentials |
| Key responsibility | Translates between your API and carrier-specific protocols |
| Privacy guarantee | Never stores phone numbers; processes in memory only |
Mobile Carrier Networks
The telecommunications providers that own the phone numbers.
| Aspect | Description |
|---|---|
| What it does | Provides the authoritative verification of phone number ownership |
| Key capability | Validates SIM credentials against their subscriber database |
| Returns | Cryptographically signed verification result |
Authentication Flow Overview
The flow consists of three main steps that happen in sequence:
Your Backend
Glide API
Returns Data
Strategy Data
Your Client App
Browser / OS
Returns Credential
(SIM/Carrier)
Your Backend
Glide API
Verification Result
Success Status
Detailed Sequence Diagram
The following diagram shows the complete flow for phone number verification:
Supported Authentication Strategies
Glide automatically selects the best strategy based on the user's device, carrier, and platform:
TS43 Strategy
| Aspect | Details |
|---|---|
| Platforms | Android (Google Play Services 24.0+), Chrome-based browsers (v141+) |
| User Experience | OS-level bottom sheet prompts user to approve consent & verification |
| How it works | Digital Credentials API accesses SIM credentials via Credential Manager |
Technical Details:
- Uses Android's Jetpack Credential Manager library
- Web browsers use the W3C Digital Credentials API
- Credential is an SD-JWT signed by the carrier
- Works over any internet connection (WiFi, cellular, etc.)
Link Strategy (Carrier App Clip / App Link)
| Aspect | Details |
|---|---|
| Where it runs | Any device whose carrier supports the App Clip / App Link redirect-with-code handoff — both mobile web (mobile browser) and native (iOS / Android apps). Glide's Magical Auth service selects this strategy server-side using both the carrier and the caller's user agent. |
| User Experience | The SDK opens the carrier App Clip; the carrier authenticates the SIM and the result returns to your app |
| How it works | Single OAuth-style flow with two return-channel modes the FE SDK selects at runtime |
Two return-channel modes (FE SDK chooses based on runtime; backend is identical):
- Mobile web — browser opens the carrier App Clip in a new tab → completion-page redirect → device binding via HttpOnly cookie (
fe_code) + URL fragment (agg_code) → original tab observes alocalStoragesignal to retrieve the result. (Used by the Web SDK in mobile browsers.) - Native (iOS / Android) — app opens the carrier App Clip → app-to-app return via Universal Link (iOS) / App Link (Android) → device binding via Secure Enclave / hardware-keystore P-256 signature (private key never leaves the device). (Used by the React Native and Android SDKs.)
Technical Details:
- Uses OS-privileged App Clip / App Link entitlements to talk to the SIM
- Device binding is mandatory — prevents session fixation via cryptographic dual-code (mobile web) or hardware-backed signature (native) validation (details)
Desktop Strategy (QR Code)
| Aspect | Details |
|---|---|
| Supported Scenarios | Desktop browsers without SIM access |
| Platforms | Any desktop browser |
| User Experience | Scan QR code with mobile phone to verify |
| How it works | Cross-device authentication via mobile companion |
Technical Details:
- Desktop shows QR code with session information
- Mobile device scans and completes TS43 or Link flow
- The
/processcall (verify-phone-number or get-phone-number) blocks server-side via Redis Pub/Sub — no client-side status polling is needed - If the mobile device hasn't completed within the server wait window (~30s), the server returns 202 Accepted with
retry: true— the SDK re-issues the same/processrequest - During rolling deploys, the server may return 503 with a
Retry-Afterheader — retry after the indicated interval (typically 1s) - Visual challenge pattern prevents phishing attacks
Data Flow Summary
| Step | From | To | Data |
|---|---|---|---|
| 1 | Your Backend | Glide API | phone_number, use_case, consent_data, client_info |
| 2 | Glide API | Your Backend | session, authentication_strategy, data |
| 3 | Your Client | User's Browser | Strategy-specific prompt data |
| 4 | User's Device | Your Client | Encrypted credential token |
| 5 | Your Backend | Glide API | session, credential |
| 6 | Glide API | Carrier | Credential validation request |
| 7 | Carrier | Glide API | Verified phone number + fraud detection signals |
| 8 | Glide API | Your Backend | phone_number, verified status, sim_swap + device_swap fraud detection |
Anti-Fraud Signals
Both verifyPhoneNumber() and getPhoneNumber() responses include SIM swap and device swap (IMEI change) fraud detection signals. These help identify potential account takeover attempts.
Both signals share the same structure:
| Field | Type | Description |
|---|---|---|
checked | boolean | Whether the check completed successfully |
risk_level | string | RISK_LEVEL_LOW, RISK_LEVEL_MEDIUM, RISK_LEVEL_HIGH, or RISK_LEVEL_UNKNOWN |
age_band | string | Time since last SIM/device change |
carrier_name | string | Carrier that performed the check (e.g., "Verizon Wireless") |
checked_at | string | RFC3339 timestamp of when the check was performed |
reason | string | Reason for check failure (only when checked=false) |
Age Band Values:
- Recent changes:
0-4 hours,4-12 hours,12 hours - 1 day,1-2 days,2-5 days,5-7 days - Older changes:
7-14 days,14-30 days,30-60 days,60-90 days,90-180 days - Default:
older than query window(when SIM/device hasn't changed recently)
Granular API (Recommended)
The SDK provides both a high-level authenticate() method and a granular step-by-step API. The granular approach is recommended for production.
Call prepare() early to determine upfront if Magical Auth is available for this user, or if you should use your OTP fallback.
// 1. Call prepare() early - as soon as you have the phone number
try {
prepareResponse = await client.prepare({
use_case: USE_CASE.VERIFY_PHONE_NUMBER,
phone_number: '+14155551234'
});
// Magical Auth available - show instant verify button
} catch (error) {
// Not eligible - show OTP fallback instead
}
// 2. When user clicks, invoke browser prompt (instant)
const invokeResult = await client.invokeSecurePrompt(prepareResponse);
const credential = await invokeResult.credential;
// 3. Complete verification
const result = await client.verifyPhoneNumber(credential, prepareResponse.session);
High-Level (authenticate()) | Granular (prepare() → invoke() → process()) |
|---|---|
| Great for demos and testing | Recommended for production |
| Single function call | Full control over each step |
| User waits during eligibility check | Know eligibility before user clicks |
| Can't show fallback upfront | Graceful fallback to OTP if not eligible |
Security Features
- End-to-end encryption - All data encrypted in transit using TLS 1.3
- Carrier signatures - Credentials cryptographically signed by carriers using ECDSA
- No phone storage - Phone numbers never stored on Glide servers; processed in memory only
- Session isolation - Each verification uses a unique session with cryptographic nonce
- Short-lived tokens - All credentials and sessions expire within minutes
- Device binding (Link Protocol) - Cryptographic dual-code binding prevents session fixation and phishing attacks. The backend generates
fe_code(stored as an HttpOnly cookie) and Glide generatesagg_code(delivered via URL fragment). Both must be validated via/completebefore results are released. Read the full guide →
Learn More
- Quickstart Guide - Get started in 5 minutes
- Error Handling - Handle edge cases gracefully
- Device Binding Security - Understand the anti-phishing mechanism for Link Protocol