Multi-Factor Authentication Architecture: Building MFA Infrastructure That Scales
Multi-factor authentication is no longer optional for production systems handling sensitive data. Every major compliance framework from PCI-DSS to SOC 2 mandates MFA for privileged access, and credential stuffing attacks have made password-only authentication a liability. But implementing MFA at scale introduces architectural challenges that go beyond bolting a TOTP library onto your login form. The authentication layer must handle millions of verification requests per second, maintain session state across distributed infrastructure, gracefully degrade when MFA services fail, and adapt verification requirements based on real-time risk signals. This article examines the infrastructure behind each major MFA factor type, the session management patterns that make MFA work at CDN edge scale, and the adaptive risk scoring architectures that determine when additional factors should be required.
How Does Multi-Factor Authentication Work at the Infrastructure Level?
Multi-factor authentication requires users to prove their identity using at least two of three factor categories: something the user knows (password, PIN), something the user has (phone, security key, smart card), and something the user is (fingerprint, face, iris). Each factor category addresses different attack vectors, and combining factors from different categories ensures that compromising one factor alone is insufficient for unauthorized access.
At the infrastructure level, MFA introduces a secondary verification step between initial credential validation and session establishment. The authentication server validates the primary credential (typically a password hash comparison), then challenges the user with a second factor before issuing the session token. This challenge-response exchange must complete within a timeout window, typically 60 to 300 seconds, after which the partial authentication state expires. The session token issued after successful MFA carries metadata indicating which factors were verified and at what assurance level, enabling downstream services to enforce security policies based on authentication strength.
TOTP: time-based one-time password implementation
TOTP, defined in RFC 6238, is the most widely deployed MFA factor for web applications. The algorithm generates a 6-digit code every 30 seconds by computing HMAC-SHA1 over a shared secret and the current time step. During enrollment, the server generates a random 160-bit secret, encodes it in base32, and presents it to the user as a QR code containing an otpauth:// URI. The user scans the QR code with an authenticator app (Google Authenticator, Authy, 1Password) which stores the secret and begins generating codes.
| Metric | Edge Processing | Origin Processing | Improvement |
|---|---|---|---|
| Latency (p50) | 8–15 ms | 120–300 ms | 15–20x faster |
| Cache Hit Ratio | 85–95% | N/A | Reduces origin load |
| TLS Handshake | 1–5 ms (nearby PoP) | 50–150 ms | 10–30x faster |
| Bandwidth Cost | $0.01–0.04/GB | $0.05–0.12/GB | 3–5x cheaper |
| Availability | 99.99% (multi-PoP) | 99.9% (single DC) | 10x fewer outages |
The TOTP verification algorithm accepts codes from the current time step plus one step before and after to account for clock drift between the server and the authenticator device. This creates a 90-second window of validity for any given code. Servers must also maintain a replay prevention record that stores the last successfully used time step per user, rejecting any code generated at or before that time step.
# TOTP verification pseudocode (RFC 6238)
function verify_totp(secret, submitted_code, user_id):
current_time = floor(unix_timestamp() / 30) # 30-second time step
last_used = get_last_used_timestep(user_id)
for offset in [-1, 0, 1]: # Allow +/- 1 step drift
time_step = current_time + offset
if time_step <= last_used:
continue # Prevent replay
hmac_result = HMAC-SHA1(secret, int_to_bytes(time_step))
offset_byte = hmac_result[19] & 0x0F
truncated = hmac_result[offset_byte:offset_byte+4] & 0x7FFFFFFF
code = truncated % 1000000 # 6 digits
if constant_time_compare(code, submitted_code):
set_last_used_timestep(user_id, time_step)
return true
return false
TOTP verification is computationally lightweight: a single HMAC-SHA1 computation per time step comparison. This makes TOTP an ideal candidate for edge function deployment. An edge function can store the encrypted TOTP secret in edge key-value storage, decrypt it at verification time, and validate the submitted code without any origin roundtrip. The entire verification completes in under 1 millisecond of CPU time.
The primary weakness of TOTP is its vulnerability to real-time phishing. An attacker who operates a convincing phishing site can relay the victim's submitted TOTP code to the legitimate server within the 30-second validity window. This phishing vulnerability is the primary motivation for migrating to WebAuthn-based factors, which are cryptographically bound to the origin domain and cannot be relayed to a different site.
WebAuthn: public key authentication as a second factor
WebAuthn, standardized by the W3C and built on the FIDO2 protocol, uses public key cryptography to authenticate users. During registration, the authenticator device generates a unique key pair. The public key is sent to the relying party (your server) and stored alongside the user's account. The private key never leaves the authenticator. During authentication, the server sends a random challenge, the authenticator signs it with the private key, and the server verifies the signature using the stored public key.
WebAuthn credentials are scoped to the relying party's origin (the combination of scheme, domain, and port). A credential registered on login.example.com cannot be used on phishing-example.com, making WebAuthn fundamentally resistant to phishing attacks. This origin binding happens at the authenticator level, not in JavaScript, so it cannot be bypassed by client-side manipulation.
Two categories of WebAuthn authenticators exist. Platform authenticators are built into the device: Touch ID on MacBook, Windows Hello, Android biometric. Roaming authenticators are external devices: YubiKey, Titan Security Key, smart cards. Passkeys, introduced by the FIDO Alliance in 2022, are synced platform authenticators where the credential synchronizes across devices through the platform vendor's cloud (Apple Keychain, Google Password Manager). Synced passkeys trade some security (the private key exists in cloud storage) for dramatically better usability (no device-specific enrollment).
Push notification MFA: architecture and trade-offs
Push-based MFA sends an approval request to the user's registered mobile device through a push notification service (APNs for iOS, FCM for Android). The user views the request details (application name, IP address, geographic location) and taps Approve or Deny. Push MFA provides a better user experience than TOTP because there are no codes to transcribe, but it introduces architectural dependencies that TOTP avoids.
The push notification flow requires four infrastructure components: a registration service that associates user accounts with device push tokens, a push delivery service that routes approval requests through APNs/FCM, a callback endpoint that receives the user's approval or denial, and a polling or WebSocket connection that informs the waiting authentication flow of the outcome. The push delivery path is inherently asynchronous and cannot be performed at the CDN edge because it requires origin-side state management and push service credentials.
Number matching is a critical security enhancement for push MFA that prevents MFA fatigue attacks. Instead of a simple approve/deny prompt, the authentication server displays a two-digit number on the login screen and the push notification asks the user to select the matching number from three options. This forces the user to actively participate in the authentication rather than reflexively tapping Approve on a notification they did not initiate. Without number matching, an attacker who has the user's password can repeatedly trigger push notifications until the user approves one out of annoyance or confusion.
Session management across distributed edge infrastructure
After successful MFA verification, the authentication server issues a session token that encodes the authentication factors used, the assurance level achieved, and the timestamp of verification. This token travels with every subsequent request through the CDN architecture, where edge nodes must validate the token without contacting the origin for each request.
JWT (JSON Web Token) is the standard format for MFA-aware session tokens in distributed systems. The token includes standard claims (sub, iat, exp) plus authentication-specific claims defined in RFC 9068: acr (Authentication Context Class Reference, indicating the authentication strength), amr (Authentication Methods References, listing the factors used such as ["pwd", "otp"] or ["pwd", "hwk"]), and aal (Authenticator Assurance Level, with values 1 through 3 corresponding to NIST SP 800-63B assurance levels).
# JWT session token with MFA claims
{
"sub": "user_8f3a2b1c",
"iss": "auth.example.com",
"iat": 1727740800,
"exp": 1727827200,
"acr": "urn:example:mfa",
"amr": ["pwd", "otp"],
"aal": 2,
"auth_time": 1727740800,
"step_up_time": null,
"client_ip": "203.0.113.42",
"device_id": "d_9e8f7a6b"
}
Edge nodes validate the JWT signature using the authentication server's public key, which is cached at the edge through JWKS (JSON Web Key Set) endpoint polling. The edge node verifies the signature, checks the exp claim for token expiration, and reads the aal claim to determine whether the session meets the token authentication requirements for the requested resource. Resources requiring MFA can be enforced entirely at the edge by checking that aal >= 2 in the session token, with no origin involvement.
Adaptive MFA: risk-based authentication decisions
Static MFA policies that require a second factor for every login create unnecessary friction for legitimate users while doing nothing to adjust security posture in response to actual threat signals. Adaptive MFA evaluates risk signals in real time and adjusts the authentication requirements accordingly. Low-risk sessions (recognized device, familiar IP address, normal access patterns) may proceed with password-only authentication. High-risk sessions (new device, unusual location, anomalous behavior, VPN or Tor exit node) trigger additional verification factors.
Risk scoring engines evaluate multiple signal categories:
- Device signals: device fingerprint match, operating system version, browser characteristics, screen resolution, installed fonts. A recognized device with a stored device cookie reduces the risk score.
- Network signals: IP address reputation, geographic location, ISP classification, VPN/proxy/Tor detection, IP velocity (how many accounts have authenticated from this IP in the scoring window).
- Behavioral signals: typing cadence during credential entry, mouse movement patterns, time of access relative to the user's historical patterns, resource access patterns.
- Account signals: recent password change, recent recovery code use, number of failed authentication attempts in the lookback window, account age, privilege level.
The risk engine produces a numerical score (typically 0.0 to 1.0) that maps to authentication requirements through configurable thresholds. A score below 0.3 might allow password-only access. A score between 0.3 and 0.7 requires TOTP or push MFA. A score above 0.7 requires a phishing-resistant factor (WebAuthn) or blocks access pending manual review. These thresholds are tuned over time using authentication outcome data: successful logins, confirmed account takeovers, false positive rates for MFA challenges.
Implementing adaptive MFA at edge scale requires a real-time signal aggregation pipeline. Device and network signals are available at the CDN edge from the incoming request headers and TLS connection metadata. Behavioral signals require client-side collection through the login page. Account signals require a database lookup, which can be served from an edge-cached user risk profile that the origin updates asynchronously. The edge function computes a preliminary risk score from available signals and includes it in the authentication request forwarded to the origin, where the full risk engine refines the score with database-backed signals.
Step-up authentication and assurance level enforcement
Step-up authentication extends the MFA model by requiring additional verification when a user who already holds an authenticated session attempts a sensitive operation. Rather than treating authentication as a binary gate at login time, step-up authentication treats it as a continuous spectrum where different operations require different assurance levels.
The session token's aal claim and auth_time timestamp drive step-up decisions. A session authenticated with password-only (AAL 1) may access read-only resources but must step up to AAL 2 (MFA) for write operations. A session at AAL 2 may need to step up to AAL 3 (hardware authenticator) for administrative actions. Additionally, even a session at the correct AAL may require re-authentication if the auth_time exceeds a freshness threshold, typically 5 to 15 minutes for the most sensitive operations.
At the CDN edge, step-up enforcement works through a policy engine that maps request paths and methods to minimum AAL requirements and maximum auth_time age. The edge function parses the JWT, compares the claims against the policy, and either forwards the request (requirements met), returns a 403 with a step-up challenge URI (requirements not met), or returns a 401 (session expired). This policy-based approach keeps the step-up logic at the edge, avoiding origin roundtrips for policy evaluation while allowing the origin to update policies through a cached configuration endpoint.
MFA enrollment and recovery infrastructure
The enrollment flow for each MFA factor type requires its own infrastructure. TOTP enrollment generates a cryptographically random secret, stores it encrypted in the user database, and presents it as a QR code. The enrollment flow must verify that the user's authenticator app correctly generates codes by requiring a validation code before activating the factor. Without this verification step, users who fail to properly scan the QR code will be locked out of their account.
WebAuthn enrollment invokes the browser's navigator.credentials.create() API with the relying party ID (your domain), a random challenge, user information, and supported algorithm preferences (-7 for ES256, -257 for RS256). The authenticator response includes the public key, credential ID, attestation statement (proving the authenticator's make and model), and transport hints (USB, NFC, BLE, internal). The server stores all of these for future authentication and transport-appropriate UI hints.
Recovery infrastructure must handle the scenario where users lose access to all enrolled MFA devices. Recovery codes (pre-generated one-time-use codes) are the most common fallback. The server generates 8 to 10 codes during enrollment, displays them once, and stores only their bcrypt hashes. Each code is consumed on use and cannot be reused. An alternative recovery path uses a trusted contact or administrator who can temporarily disable MFA on the account through a compliance-approved identity verification process.
Monitoring MFA enrollment and usage metrics is essential for operational visibility. Track the percentage of users with MFA enrolled, the distribution of factor types, the success and failure rates per factor, the average verification latency, and the rate of recovery code usage. Spikes in recovery code usage may indicate a compromised authenticator app ecosystem or a social engineering campaign targeting your support team. Integration with your CDN monitoring stack provides visibility into edge-side MFA verification latency and error rates across all PoPs.
Production hardening: rate limiting and anti-automation
The MFA verification endpoint is a high-value target for brute-force attacks. A 6-digit TOTP code has only 1,000,000 possible values, and the 90-second validity window gives an attacker approximately 3 valid codes at any given time. Without rate limiting, an attacker who knows the user's password could enumerate TOTP codes at scale. The CDN rate limiting layer must enforce strict per-account rate limits on the MFA verification endpoint: typically 5 attempts per minute per account, with exponential backoff after 3 consecutive failures.
Additional protections include binding the MFA challenge to the session that initiated it (preventing challenge replay across sessions), requiring a valid mfa_token from the initial password verification step, implementing CAPTCHA after repeated failures, and alerting the user via email when MFA failures exceed a threshold. The bot management layer at the CDN edge should apply device fingerprinting and behavioral analysis to MFA verification requests, blocking automated submission tools before they reach the rate limiting layer.
TLS client certificate pinning between the CDN edge and the authentication origin ensures that origin protection is maintained even if an attacker manages to route traffic directly to the origin, bypassing edge security controls. Combined with mutual TLS, this creates a defense-in-depth architecture where the MFA infrastructure is protected at both the edge and origin layers through WAF rules and security headers that enforce the expected authentication flow.
Building MFA infrastructure that scales requires thinking beyond the authentication moment. The factor verification itself is computationally trivial. The engineering challenge lies in distributed session management, graceful degradation when MFA services are unavailable, adaptive risk scoring at edge latency budgets, and the enrollment and recovery flows that determine whether users actually adopt the stronger factors you offer. Start with TOTP for broad coverage, add WebAuthn for phishing resistance, implement adaptive risk scoring to reduce unnecessary friction, and instrument every step to catch anomalies before they become incidents.