This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
securitycritical PriorityID: webauthn-conditional-mediation-channel-binding-guardrail

WebAuthn Conditional Mediation Cross-Origin Challenge Binding Guardrail

Enforces cryptographic binding between WebAuthn conditional mediation (passkey autofill) challenges, transient browser nonces, and TLS channel/session tokens to neutralize cross-origin relay and session replay attacks. Mandates strict RP ID validation, cryptographically random challenge-to-session association in isolated cache layers, and clientDataJSON origin/type parity checking during public key credential assertion verification.

Prohibited Anti-Pattern: Unbound Ephemeral Challenges Allowing Cross-Origin Passkey Autofill Replay and Credential Stuffing

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: WebAuthn Conditional Mediation Cross-Origin Challenge Binding Guardrail - Enforces cryptographic binding between WebAuthn conditional mediation (passkey autofill) challenges, transient browser nonces, and TLS channel/session tokens to neutralize cross-origin relay and session replay attacks. Mandates strict RP ID validation, cryptographically random challenge-to-session association in isolated cache layers, and clientDataJSON origin/type parity checking during public key credential assertion verification.
globs: src/auth/**/*.{ts,tsx}, src/server/auth/**/*.{ts,tsx}, src/pages/api/auth/**/*.{ts,tsx}, src/services/webauthn/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/webauthn-conditional-mediation-channel-binding-guardrail"
---

# WebAuthn Conditional Mediation Cross-Origin Challenge Binding Guardrail

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Unbound Ephemeral Challenges Allowing Cross-Origin Passkey Autofill Replay and Credential Stuffing

## System Constraints
You are a Principal Security Architect enforcing the WebAuthn Conditional Mediation Cross-Origin Challenge Binding Guardrail. You must prohibit unbound, static, or client-supplied challenges in passkey autofill flows. Enforce single-use, cryptographically secure challenges bound to TLS session/cookie tokens, verify that clientDataJSON origin and RP ID strictly match canonical server configuration, and mandate that conditional UI assertions are atomically consumed and invalidated upon first verification attempt.

## Strict Guidelines
- Services MUST generate cryptographically secure pseudorandom challenges (minimum 32 bytes via crypto.randomBytes) per conditional assertion session and persist them in an encrypted, short-lived (<= 120s TTL) session-bound store.
- Engineers MUST ALWAYS bind the WebAuthn challenge to the client's secure, HTTP-only, SameSite=Strict ephemeral session token or TLS exporter token to prevent cross-session relay.
- Engineers MUST NOT allow client-supplied challenge generation or accept challenges cached globally without tenant/session isolation.
- Verification routines MUST strictly compare clientDataJSON.origin against an explicit allowlist of canonical origins, rejecting any origin mismatch or wildcards.
- Verification routines MUST assert that clientDataJSON.type equals 'webauthn.get' and atomically purge the challenge from storage prior to signature validation to prevent replay.
- Components NEVER render conditional passkey mediation (`mediation: 'conditional'`) without verifying browser platform support (`PublicKeyCredential.isConditionalMediationAvailable()`) and obtaining a freshly issued, session-bound challenge.

## Bad vs Good Implementations
### Insecure Conditional Assertion Verification (Vulnerable to Replay and Origin Spoofing)

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Accepting the expected challenge from the client request body and relying on dynamic `req.headers.origin` allows attackers to relay signed passkey assertions across contexts and perform session replay or MITM credential relay.
```typescript
import { Request, Response } from 'express';
import { verifyAuthenticationResponse } from '@simplewebauthn/server';

// ANTI-PATTERN: Challenge is stored globally or passed back by client
// Missing ephemeral TLS/session binding and strict origin verification
export async function verifyPasskeyAutofill(req: Request, res: Response) {
  const { credential, expectedChallenge } = req.body;

  // Flaw 1: Trusting client-supplied expectedChallenge
  // Flaw 2: Origin is loosely checked using client-controlled headers
  const verification = await verifyAuthenticationResponse({
    response: credential,
    expectedChallenge,
    expectedOrigin: req.headers.origin as string,
    expectedRPID: 'example.com',
    requireUserVerification: false
  });

  if (verification.verified) {
    return res.json({ success: true, userId: verification.authenticationInfo.userId });
  }
  return res.status(401).json({ error: 'Unauthorized' });
}
```

#### Production Standard (Correct)
> **Standard**: Binds challenge lookup directly to a SHA-256 hashed `__Host-` transient session cookie, uses atomic Redis `GETDEL` for single-use consumption, and enforces static compile-time/environment origins and RP IDs with mandatory user verification.
```typescript
import { Request, Response } from 'express';
import { verifyAuthenticationResponse } from '@simplewebauthn/server';
import { redisClient } from '../lib/redis';
import crypto from 'node:crypto';

const CANONICAL_ORIGIN = process.env.AUTH_CANONICAL_ORIGIN!;
const CANONICAL_RP_ID = process.env.AUTH_RP_ID!;

export async function verifyPasskeyAutofillSecure(req: Request, res: Response) {
  const sessionToken = req.cookies['__Host-auth-transient-nonce'];
  if (!sessionToken || typeof sessionToken !== 'string') {
    return res.status(401).json({ error: 'Missing transient session token' });
  }

  const sessionTokenHash = crypto.createHash('sha256').update(sessionToken).digest('hex');
  const challengeKey = `webauthn:challenge:${sessionTokenHash}`;

  // Atomically retrieve and delete challenge to enforce single-use invariant
  const storedChallenge = await redisClient.getdel(challengeKey);
  if (!storedChallenge) {
    return res.status(401).json({ error: 'Challenge expired, missing, or already consumed' });
  }

  const { credential } = req.body;

  try {
    const verification = await verifyAuthenticationResponse({
      response: credential,
      expectedChallenge: storedChallenge,
      expectedOrigin: CANONICAL_ORIGIN,
      expectedRPID: CANONICAL_RP_ID,
      requireUserVerification: true
    });

    if (!verification.verified) {
      return res.status(401).json({ error: 'Passkey verification failed' });
    }

    return res.json({ success: true, userId: verification.authenticationInfo.userId });
  } catch (error) {
    return res.status(400).json({ error: 'Invalid assertion payload' });
  }
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: WebAuthn Conditional Mediation Cross-Origin Challenge Binding Guardrail

WebAuthn Conditional Mediation Cross-Origin Challenge Binding Guardrail defines an industrial-grade behavioral standard for security engineering. Enforces cryptographic binding between WebAuthn conditional mediation (passkey autofill) challenges, transient browser nonces, and TLS channel/session tokens to neutralize cross-origin relay and session replay attacks. Mandates strict RP ID validation, cryptographically random challenge-to-session association in isolated cache layers, and clientDataJSON origin/type parity checking during public key credential assertion verification. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Unbound Ephemeral Challenges Allowing Cross-Origin Passkey Autofill Replay and Credential Stuffing Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftUnbound Ephemeral Challenges Allowing Cross-Origin Passkey Autofill Replay and Credential StuffingCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Services MUST generate cryptographically secure pseudorandom challenges (minimum 32 bytes via crypto.randomBytes) per conditional assertion session and persist them in an encrypted, short-lived (<= 120s TTL) session-bound store.

Services MUST generate cryptographically secure pseudorandom challenges (minimum 32 bytes via crypto.randomBytes) per conditional assertion session and persist them in an encrypted, short-lived (<= 120s TTL) session-bound store.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST ALWAYS bind the WebAuthn challenge to the client's secure, HTTP-only, SameSite=Strict ephemeral session token or TLS exporter token to prevent cross-session relay.

Engineers MUST ALWAYS bind the WebAuthn challenge to the client's secure, HTTP-only, SameSite=Strict ephemeral session token or TLS exporter token to prevent cross-session relay.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST NOT allow client-supplied challenge generation or accept challenges cached globally without tenant/session isolation.

Engineers MUST NOT allow client-supplied challenge generation or accept challenges cached globally without tenant/session isolation.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Verification routines MUST strictly compare clientDataJSON.origin against an explicit allowlist of canonical origins, rejecting any origin mismatch or wildcards.

Verification routines MUST strictly compare clientDataJSON.origin against an explicit allowlist of canonical origins, rejecting any origin mismatch or wildcards.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Verification routines MUST assert that clientDataJSON.type equals 'webauthn.get' and atomically purge the challenge from storage prior to signature validation to prevent replay.

Verification routines MUST assert that clientDataJSON.type equals 'webauthn.get' and atomically purge the challenge from storage prior to signature validation to prevent replay.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
6

Components NEVER render conditional passkey mediation (`mediation

Components NEVER render conditional passkey mediation (`mediation: 'conditional'`) without verifying browser platform support (`PublicKeyCredential.isConditionalMediationAvailable()`) and obtaining a freshly issued, session-bound challenge.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is WebAuthn Conditional Mediation Cross-Origin Challenge Binding Guardrail critical for AI coding assistants?

Enforces cryptographic binding between WebAuthn conditional mediation (passkey autofill) challenges, transient browser nonces, and TLS channel/session tokens to neutralize cross-origin relay and session replay attacks. Mandates strict RP ID validation, cryptographically random challenge-to-session association in isolated cache layers, and clientDataJSON origin/type parity checking during public key credential assertion verification. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Unbound Ephemeral Challenges Allowing Cross-Origin Passkey Autofill Replay and Credential Stuffing) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

WebAuthn