Step-Up Authentication: Progressive Security for Sensitive Edge Operations

· Sarah Mitchell · 12 min read

Not every API request deserves the same level of scrutiny. When a user browses a product catalog behind a CDN, a simple session cookie suffices. When that same user changes their payment method, transfers funds, or modifies account permissions, the system should demand stronger proof of identity — even though the user already logged in minutes ago. This is the core premise of step-up authentication: a progressive security model that escalates identity verification based on the sensitivity of the operation being attempted, rather than applying a single authentication level uniformly at the front door.

The challenge becomes significantly harder when your application runs behind a distributed CDN with hundreds of edge servers across dozens of points of presence. Traditional step-up authentication assumes a monolithic origin server that controls the full authentication lifecycle. In a CDN architecture, the edge node receiving the sensitive request may be thousands of miles from the identity provider, and the round-trip latency of redirecting to the origin for re-authentication undermines the very performance gains the CDN was deployed to provide. Building step-up authentication that works natively at the edge requires rethinking how authentication state is represented, propagated, and validated across a distributed infrastructure built on zero trust principles.

What Is Step-Up Authentication and Why It Matters for CDN Operations

Step-up authentication, also called progressive authentication or adaptive authentication, is a security pattern in which the system requires a user to provide additional identity verification when they attempt to access a resource or perform an operation that is classified as sensitive. The user begins with a baseline authentication level — typically a username and password, or a single-factor session — and the system "steps up" to a higher assurance level only when the risk warrants it.

Consider an online banking application. Checking the account balance requires only a standard login. Initiating a wire transfer to a new recipient triggers a step-up: the user must confirm with a biometric scan, hardware security key, or one-time passcode before the operation proceeds. The baseline session remains valid for low-risk actions; the step-up token grants temporary elevated access that expires after a short window.

This pattern exists because uniform high-security authentication creates friction that degrades user experience. Requiring a hardware key tap for every page load is impractical. But allowing every action to proceed with only a password is insecure. Step-up authentication provides a middle path: low friction for routine operations, high assurance for sensitive ones. The MFA architecture underlying step-up defines which factors are available and when they are triggered.

For CDN-delivered applications, step-up authentication introduces architectural complexity that does not exist in monolithic deployments. The edge node processing a sensitive request must be able to determine the current authentication level of the session, compare it against the required level for the requested resource, and either allow the request, challenge the user for additional factors, or redirect to the identity provider — all without introducing latency that defeats the purpose of edge delivery. This requires careful design of token-based authentication at the edge, where the token itself carries the authentication context needed for step-up decisions.

ACR and AMR Claims: The Language of Authentication Strength

Step-up authentication depends on a standardized way to express "how strongly was this user authenticated?" The OAuth 2.0 and OpenID Connect specifications define two JWT claims for this purpose: ACR (Authentication Context Class Reference) and AMR (Authentication Methods Reference).

Performance Comparison: Edge vs Origin Processing
Metric Edge Processing Origin Processing Improvement
Latency (p50)8–15 ms120–300 ms15–20x faster
Cache Hit Ratio85–95%N/AReduces origin load
TLS Handshake1–5 ms (nearby PoP)50–150 ms10–30x faster
Bandwidth Cost$0.01–0.04/GB$0.05–0.12/GB3–5x cheaper
Availability99.99% (multi-PoP)99.9% (single DC)10x fewer outages

Authentication Context Class Reference (ACR)

The ACR claim identifies the authentication context class that was satisfied during the authentication event. It represents the overall strength or assurance level of the authentication. Common ACR values include:

# ACR values (from low to high assurance)
acr: "urn:mace:incommon:iap:bronze"    # Single factor (password only)
acr: "urn:mace:incommon:iap:silver"    # Multi-factor (password + OTP)
acr: "urn:mace:incommon:iap:gold"      # MFA with hardware token
acr: "urn:mace:incommon:iap:platinum"  # MFA + identity proofing

# Custom ACR levels (common in enterprise deployments)
acr: "https://example.com/acr/basic"       # Level 1: password
acr: "https://example.com/acr/mfa"         # Level 2: password + TOTP/SMS
acr: "https://example.com/acr/phishing-resistant"  # Level 3: FIDO2/WebAuthn
acr: "https://example.com/acr/verified"    # Level 4: Level 3 + ID verification

When a client requests authentication, it can specify the minimum ACR level required using the acr_values parameter in the authorization request. The identity provider must satisfy at least the requested level, and the resulting ID token's acr claim indicates the level actually achieved.

Authentication Methods Reference (AMR)

While ACR describes the overall strength level, AMR lists the specific methods that were used during authentication. A single authentication event might use multiple methods, and the AMR claim captures all of them:

# AMR values in a JWT payload
{
  "sub": "user-12345",
  "acr": "urn:mace:incommon:iap:silver",
  "amr": ["pwd", "otp"],          # password + one-time password
  "auth_time": 1727740800,
  "iat": 1727740800,
  "exp": 1727744400
}

# Common AMR values (RFC 8176)
# pwd  - password authentication
# otp  - one-time password (TOTP/HOTP)
# sms  - SMS-based verification
# hwk  - hardware key (FIDO U2F, FIDO2)
# swk  - software key (authenticator app)
# fpt  - fingerprint biometric
# face - facial recognition biometric
# pin  - personal identification number
# mfa  - generic multi-factor indicator
# wia  - Windows integrated authentication
# kba  - knowledge-based authentication

At the CDN edge, inspecting the AMR claim provides more granular control than ACR alone. An edge policy might require that the hwk method is present for admin API endpoints, regardless of the overall ACR level. This prevents a scenario where a compromised OTP satisfies the MFA ACR level but the endpoint specifically requires a phishing-resistant hardware key. The JWT security best practices for distributed systems apply directly here — every edge node must validate these claims cryptographically, not just parse them.

Step-Up Authentication Flow Through CDN Edge Step-Up Authentication Flow at CDN Edge Client Session: L1 acr: basic Session: L2 acr: mfa CDN Edge Node 1. Parse JWT claims Extract ACR + AMR 2. Match endpoint policy /api/settings requires L2 3. ACR insufficient L1 < L2 required 4. Challenge or redirect 401 + acr_values=mfa 6. Validate step-up token ACR=mfa, session bound 7. Forward to origin Identity Provider 5. MFA challenge Issue new token Origin Server Sensitive operation GET /settings 401 step-up Retry + L2 token
Figure 1: Step-up authentication flow at the CDN edge — the edge node evaluates ACR/AMR claims, challenges for re-authentication when the operation requires a higher assurance level, and forwards only after the elevated token is validated.

Risk-Based Authentication Escalation at the Proxy Layer

Static step-up policies — "this endpoint always requires MFA" — are a starting point, but real-world threats are contextual. A legitimate user accessing their account settings from their usual device, on their usual network, during business hours, presents far less risk than the same request arriving from an unfamiliar IP address in a different country at 3 AM. Risk-based authentication escalation evaluates contextual signals at the reverse proxy layer and adjusts the required authentication level dynamically.

The risk engine at the edge evaluates multiple signals available without origin contact:

# Risk scoring policy at CDN edge (pseudocode)
risk_policy:
  signals:
    - name: ip_reputation
      source: threat_intel_feed
      weight: 0.25
      high_risk_threshold: score > 70

    - name: geo_anomaly
      source: session_geo_history
      weight: 0.20
      high_risk_threshold: distance_km > 5000 AND time_delta_hours < 2

    - name: device_fingerprint
      source: tls_ja3_hash + ua_string
      weight: 0.15
      high_risk_threshold: fingerprint != session.fingerprint

    - name: auth_age
      source: jwt.auth_time
      weight: 0.20
      high_risk_threshold: now - auth_time > 1800  # 30 minutes

    - name: endpoint_sensitivity
      source: route_config
      weight: 0.20
      levels: {read_profile: 0.2, update_email: 0.7, change_password: 0.9, delete_account: 1.0}

  escalation_thresholds:
    - score: 0.0 - 0.3   -> required_acr: "basic"
    - score: 0.3 - 0.6   -> required_acr: "mfa"
    - score: 0.6 - 0.8   -> required_acr: "phishing-resistant"
    - score: 0.8 - 1.0   -> required_acr: "verified" + rate_limit: strict

This risk-based approach aligns with the zero trust security model: never trust implicitly, always verify based on context. The edge node computes the risk score in under a millisecond using locally cached threat data and session state, then compares the computed required ACR against the token's actual ACR. If the token meets or exceeds the requirement, the request passes. If not, the edge issues a step-up challenge proportional to the gap between the current and required levels.

Risk Scoring Decision Tree at CDN Edge Risk Scoring Decision Tree at Edge Incoming Request Parse JWT + context IP Reputation w: 0.25 Geo Anomaly w: 0.20 Device FP w: 0.15 Auth Age w: 0.20 Endpoint w: 0.20 Weighted Risk Score sum(signal * weight) Allow (ACR: basic) Score 0.0 – 0.3 Step-Up: MFA Score 0.3 – 0.6 Step-Up: FIDO2 Score 0.6 – 0.8 Block + Verify Score 0.8 – 1.0 200 OK → origin 401 + acr_values=mfa 401 + acr_values=fido2 403 + identity verify
Figure 2: Risk scoring decision tree — contextual signals are weighted and aggregated to determine the required authentication level, with escalation proportional to the computed risk score.

Implementation Patterns: Edge Re-Authentication vs. Origin Redirect

When the edge determines that a step-up is required, two architectural patterns are available for executing the re-authentication. Each has distinct trade-offs for latency, security, and implementation complexity.

Pattern 1: Origin Redirect for Re-Authentication

The most straightforward pattern redirects the client to the central identity provider (IdP) for re-authentication. The edge node responds with an HTTP 302 or 307 redirect to the IdP's authorization endpoint, including the required acr_values parameter. The IdP challenges the user for the additional factor, issues a new token with the elevated ACR, and redirects back to the original resource.

# Edge node step-up response: origin redirect pattern
HTTP/1.1 302 Found
Location: https://auth.example.com/authorize
  ?response_type=code
  &client_id=edge-service-001
  &redirect_uri=https://cdn.example.com/auth/callback
  &scope=openid profile
  &acr_values=urn:mace:incommon:iap:silver
  &prompt=login
  &state=eyJvcmlnaW5hbF91cmwiOiIvYXBpL3NldHRpbmdzIn0
  &nonce=a1b2c3d4e5f6
Cache-Control: no-store
X-Step-Up-Reason: insufficient_acr

The state parameter encodes the original request URL so the user is returned to their intended destination after re-authentication. The prompt=login parameter forces the IdP to perform a fresh authentication rather than reusing an existing SSO session. This pattern works well when the IdP is the authoritative source for all authentication methods, and when the redirect latency (typically 200 to 500 milliseconds plus user interaction time) is acceptable for the use case.

Pattern 2: Edge-Local Re-Authentication

For latency-sensitive operations, the edge node can present an authentication challenge directly without redirecting to the origin. This pattern works best with WebAuthn/FIDO2 authentication, where the passkey verification can happen at the edge using pre-distributed public keys.

# Edge-local step-up: WebAuthn challenge
# 1. Edge returns 401 with challenge parameters
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer
  error="insufficient_user_authentication",
  acr_values_required="https://example.com/acr/phishing-resistant",
  max_age=300
Content-Type: application/json

{
  "step_up": {
    "challenge": "dGhpcyBpcyBhIHJhbmRvbSBjaGFsbGVuZ2U",
    "rpId": "example.com",
    "allowCredentials": [
      {"type": "public-key", "id": "credential-id-abc123"}
    ],
    "timeout": 60000,
    "userVerification": "required"
  }
}

# 2. Client performs WebAuthn ceremony and retries
POST /api/settings HTTP/1.1
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
X-Step-Up-Assertion: eyJhdHRlc3RhdGlvbiI6Ii4uLiJ9
X-Step-Up-Challenge: dGhpcyBpcyBhIHJhbmRvbSBjaGFsbGVuZ2U

The edge node validates the WebAuthn assertion against the user's registered public key (cached at the edge from the credential store), mints a short-lived step-up token, and attaches it to the session. This eliminates the origin round-trip entirely for the re-authentication step. The origin protection layer still validates the step-up token when the request arrives, providing defense in depth.

The trade-off is complexity: distributing user credential public keys to edge nodes requires a secure synchronization mechanism, and key revocation must propagate quickly. Organizations using this pattern typically cache public keys with a TTL of 5 to 15 minutes and fall back to the origin redirect pattern if the cached key is missing or expired.

Session Binding and Step-Up Tokens in Distributed CDN

A step-up token that is not cryptographically bound to the session that earned it is a security vulnerability. An attacker who steals a step-up token from a legitimate user's network traffic (or from a cross-site scripting attack) can replay it in their own session to bypass re-authentication. In a distributed CDN, where any edge node might receive the replayed token, session binding must be verifiable without centralized state.

Three-Layer Token Binding

Production step-up implementations bind the elevated token to three contextual anchors:

# Step-up token payload (JWT)
{
  "sub": "user-12345",
  "iss": "https://auth.example.com",
  "aud": "https://cdn.example.com",
  "iat": 1727740800,
  "exp": 1727741700,           # 15-minute TTL
  "acr": "urn:mace:incommon:iap:silver",
  "amr": ["pwd", "otp"],

  # Session binding claims
  "sid": "sha256:a1b2c3d4...", # Hash of session ID
  "cnf": {                      # Confirmation claim (RFC 7800)
    "jkt": "sha256:x5t_fingerprint_of_client_cert"
  },
  "client_ip_prefix": "203.0.113.0/24",  # /24 prefix, not exact IP
  "tls_binding": "sha256:ja3_hash",       # TLS fingerprint

  # Step-up scope
  "step_up_scope": ["account:write", "payment:initiate"],
  "step_up_max_uses": 5        # Limit token to N operations
}

The sid claim binds the step-up token to a specific session. The edge node computes the SHA-256 hash of the session cookie presented with the request and compares it against the sid claim. A mismatch means the token was transplanted to a different session and must be rejected. This is the same principle that underpins mutual TLS certificate binding, applied to session cookies.

The client_ip_prefix claim uses a /24 prefix rather than an exact IP to accommodate legitimate IP changes within a network (NAT traversal, mobile carrier IP rotation) while still detecting cross-network replay. The tls_binding claim captures the JA3 or JA4 fingerprint of the TLS handshake, which changes when the client software or TLS configuration changes — a signal of potential session hijacking.

Token Propagation via Signed Cookies

In a distributed CDN, the step-up token must be accessible to any edge node that might serve subsequent requests for the elevated session. Two approaches exist:

The signed cookie approach aligns with the principle that security headers and cookie attributes are the first line of defense for client-side token security. The cookie must be scoped to the minimum necessary path (e.g., Path=/api/settings rather than Path=/) to limit exposure. The OWASP broken access control guidelines emphasize that overly broad cookie scopes are a common source of privilege escalation vulnerabilities.

Integration with MFA at Edge Nodes

The step-up authentication framework must integrate with the organization's multi-factor authentication infrastructure. The specific factors available for step-up depend on what the user has enrolled and what the edge node can verify locally.

TOTP/HOTP Verification at Edge

Time-based and HMAC-based one-time passwords are the most widely deployed second factors. Verifying a TOTP code requires only the user's TOTP seed (a 20-byte shared secret) and the current time. Edge nodes can cache TOTP seeds encrypted with a key-encryption-key (KEK) distributed via the CDN's TLS infrastructure, enabling local verification without origin contact.

# TOTP verification at edge (pseudocode)
def verify_totp_at_edge(user_id, submitted_code):
    # Retrieve encrypted seed from edge cache
    encrypted_seed = edge_cache.get(f"totp_seed:{user_id}")
    if not encrypted_seed:
        # Cache miss: fall back to origin redirect
        return redirect_to_idp(acr_values="mfa")

    seed = decrypt_with_kek(encrypted_seed)

    # Check current and adjacent time windows (clock skew tolerance)
    for offset in [-1, 0, 1]:
        expected = compute_totp(seed, time_step=30, offset=offset)
        if constant_time_compare(submitted_code, expected):
            # Mint step-up token
            return issue_step_up_token(user_id, acr="mfa", amr=["pwd", "otp"])

    return {"error": "invalid_otp", "remaining_attempts": 2}

The critical security requirement is that TOTP seeds stored at edge nodes must be encrypted at rest and decrypted only in memory during verification. Compromising an edge node's disk should not expose TOTP seeds. The KEK should be rotated on a schedule aligned with the CDN's key management lifecycle, typically every 90 days.

WebAuthn/FIDO2 Verification at Edge

WebAuthn (passkey) authentication is the gold standard for phishing-resistant step-up because the cryptographic challenge-response is bound to the origin domain. The edge node generates a challenge, the client's authenticator signs it with the private key, and the edge verifies the signature against the user's registered public key.

Unlike TOTP seeds, WebAuthn public keys are not sensitive secrets — they can be cached at edge nodes without encryption. However, the credential metadata (credential ID, public key, sign count) must be kept current. A user who registers a new passkey or revokes an old one expects the change to take effect immediately. Edge caches should use a TTL of 1 to 5 minutes for WebAuthn credentials, with cache invalidation triggered by the credential store on registration or revocation events.

Push Notification MFA

Push-based MFA (where the user approves a notification on their mobile device) cannot be verified at the edge because it requires real-time communication with the push notification service and the user's device. For step-up flows requiring push MFA, the edge node must redirect to the IdP or use a WebSocket connection to the authentication backend. This introduces latency equivalent to the origin redirect pattern, making push MFA the least edge-friendly second factor.

Performance Considerations for Progressive Authentication

Step-up authentication adds latency at two points: the policy evaluation (deciding whether step-up is required) and the step-up execution (performing the re-authentication). Minimizing both is essential for maintaining the performance metrics that justify edge delivery.

Policy Evaluation Overhead

For requests that do not trigger step-up (the vast majority), the overhead is the time to parse the JWT, extract ACR/AMR claims, compute the risk score, and compare against the endpoint policy. This should take 0.1 to 0.5 milliseconds on modern edge hardware — negligible compared to TLS handshake and network latency. The TLS 1.3 handshake itself adds 1 to 2 RTTs, dwarfing the policy evaluation time.

Key optimizations for policy evaluation:

Step-Up Execution Latency

When step-up is triggered, the latency depends entirely on the pattern used:

PatternAdded LatencyUser InteractionEdge Complexity
Origin redirect (TOTP)200–500ms + user timeType 6-digit codeLow (redirect only)
Origin redirect (push MFA)200–500ms + 5–30sTap approveLow
Edge-local TOTP5–20ms + user timeType 6-digit codeMedium (seed cache)
Edge-local WebAuthn5–20ms + user timeTouch/biometricMedium (key cache)
Transparent (risk only)0.5ms (inline)NoneHigh (risk engine)

The "transparent" row represents risk-based decisions that adjust rate limits or throttling without interrupting the user, used when the risk score is slightly elevated but not enough to warrant a full step-up challenge. For example, a request from an unusual IP might be allowed but rate limited more aggressively, with the step-up challenge triggered only if the suspicious behavior continues.

Caching Elevated Authentication State

The most important performance optimization is caching the elevated authentication state so that subsequent sensitive requests within the step-up TTL window do not trigger re-authentication. A user who completes MFA to access account settings should not be challenged again when they navigate to payment methods 30 seconds later, assuming both endpoints require the same ACR level.

The step-up token's step_up_scope claim defines which operations are covered by the elevated state. Scoping should be broad enough to avoid repeated challenges during a single workflow but narrow enough to enforce the principle of least privilege. A scope of ["account:*"] covers all account management operations; a scope of ["payment:initiate"] covers only payment initiation and requires a fresh step-up for other sensitive operations.

The edge computing capabilities of modern CDNs make all of these patterns feasible at global scale. Edge workers can execute authentication logic in under a millisecond, and distributed KV stores provide the session state needed for token binding and revocation. The key architectural decision is where to draw the line between edge-local verification (fast but complex to maintain) and origin-delegated verification (simpler but slower).

Securing the Step-Up Flow Against Attack Vectors

Step-up authentication introduces its own attack surface that must be addressed in the edge security design. The DDoS protection and WAF layers provide the foundation, but step-up-specific attacks require targeted defenses.

Step-Up Fatigue Attacks

An attacker who has compromised a user's password but not their second factor can trigger repeated step-up challenges, hoping the user approves one out of frustration (the same technique used in MFA fatigue attacks). Edge defenses include:

Token Downgrade Attacks

An attacker might modify the request to target a lower-sensitivity endpoint (which requires a lower ACR) and then alter the response to serve the sensitive resource. Edge defenses must ensure that the ACR check is performed on the actual resource being served, not just the requested URL. This requires the origin to echo the required ACR in its response headers, which the edge validates before forwarding to the client. The distinction between 401 and 403 becomes critical here: 401 signals that authentication can be escalated, while 403 signals that the user lacks authorization regardless of authentication level.

Session Fixation via Step-Up

If the step-up flow does not rotate the session identifier after successful re-authentication, an attacker who has fixated the session before step-up can hijack the elevated session. The edge must issue a new session cookie (and invalidate the old one) after every successful step-up, just as it would after initial login. The CORS and security header configurations must be tight enough to prevent cross-origin access to the elevated session cookie.

Deploying Step-Up Authentication: A Reference Architecture

Bringing all the pieces together, a production step-up authentication deployment at CDN scale involves coordination between several components. The load balancing layer routes authentication traffic, the edge evaluates policies, and the origin manages the credential store.

The edge configuration maps endpoints to required ACR levels:

# Edge step-up policy configuration
step_up_policy:
  default_acr: "basic"
  default_ttl: 3600          # 1 hour for basic sessions

  endpoints:
    # Public endpoints: no auth required
    - pattern: "/api/v1/products/*"
      required_acr: null
      methods: [GET]

    # Standard authenticated endpoints
    - pattern: "/api/v1/user/profile"
      required_acr: "basic"
      methods: [GET]

    # Sensitive read operations
    - pattern: "/api/v1/user/sessions"
      required_acr: "mfa"
      step_up_ttl: 900        # 15-minute elevated window
      methods: [GET]

    # Sensitive write operations
    - pattern: "/api/v1/user/email"
      required_acr: "mfa"
      amr_required: ["pwd", "otp"]  # Specific methods required
      step_up_ttl: 300
      methods: [PUT, PATCH]

    # Critical operations
    - pattern: "/api/v1/user/password"
      required_acr: "phishing-resistant"
      amr_required: ["hwk"]         # Hardware key required
      step_up_ttl: 120
      methods: [PUT]

    # Admin operations
    - pattern: "/api/v1/admin/*"
      required_acr: "phishing-resistant"
      amr_required: ["hwk"]
      step_up_ttl: 300
      risk_scoring: enabled         # Dynamic escalation
      methods: [GET, POST, PUT, DELETE]

  risk_overrides:
    high_risk_bump: 1               # Bump required ACR by 1 level
    impossible_travel: block        # Block and require full re-auth

The API gateway authorization layer enforces these policies before routing to the origin. Each edge PoP evaluates the policy locally using the JWT claims and cached risk data, ensuring that authentication decisions happen at the speed of edge computing rather than the speed of origin round-trips.

The AI agent authorization use case is particularly relevant for step-up authentication. AI agents that operate on behalf of users may need to escalate authentication when they attempt sensitive operations, and the edge must be able to distinguish between the agent's own credentials and the delegated user credentials that determine the step-up requirements.

Step-up authentication at the CDN edge is not a single feature but a system design that touches token architecture, edge computing, session management, and risk assessment. The fundamental principle is simple: match the authentication strength to the sensitivity of the operation, and do it as close to the user as possible. The implementation is complex because distributed systems make everything complex. But the alternative — either uniform low security or uniform high friction — is worse for both security and user experience. Build the step-up flow into the edge from the start, bind tokens to sessions cryptographically, and use risk scoring to make intelligent escalation decisions. Your users will barely notice the security, which means you built it right. The zero trust authentication model at the edge is the future of identity-aware content delivery, and step-up is the mechanism that makes it practical without making it painful. For the underlying SSL/TLS configuration that secures these token exchanges, ensure that your edge nodes enforce modern cipher suites and certificate validation at every hop.

External References

References & Standards: W3C Web Performance · OWASP CDN Security