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

Strict RP ID and Origin Cross-Binding Guardrail for WebAuthn Conditional Mediation

Enforces cryptographic and structural validation of Relying Party ID (rpId) and clientDataJSON origin during WebAuthn conditional mediation (autofill). Eliminates cross-origin credential harvesting, subdomain credential confusion, and federated origin spoofing by requiring explicit origin allowlisting and canonical RP ID matching on server-side assertion verification.

Prohibited Anti-Pattern: Permissive Subdomain Wildcarding or Unchecked clientDataJSON Origin in Conditional WebAuthn Verification

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Strict RP ID and Origin Cross-Binding Guardrail for WebAuthn Conditional Mediation - Enforces cryptographic and structural validation of Relying Party ID (rpId) and clientDataJSON origin during WebAuthn conditional mediation (autofill). Eliminates cross-origin credential harvesting, subdomain credential confusion, and federated origin spoofing by requiring explicit origin allowlisting and canonical RP ID matching on server-side assertion verification.
globs: src/auth/**/*.{ts,tsx}, src/server/auth/**/*.{ts,tsx}, src/api/auth/**/*.{ts,tsx}, pages/api/auth/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/webauthn-conditional-mediation-origin-binding-guardrail"
---

# Strict RP ID and Origin Cross-Binding Guardrail for WebAuthn Conditional Mediation

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Permissive Subdomain Wildcarding or Unchecked clientDataJSON Origin in Conditional WebAuthn Verification

## System Constraints
You are a Principal Security Architect enforcing strict WebAuthn Relying Party ID (rpId) and clientDataJSON origin validation. When implementing or reviewing WebAuthn passkey conditional mediation flows, you must ensure that relying party identifiers cannot be relaxed to top-level domains indiscriminately, that client origins are cryptographically bound to an explicit immutable allowlist, and that cross-subdomain impersonation via autofill passkeys is prevented.

## Strict Guidelines
- Engineers MUST ALWAYS enforce strict equality between `clientDataJSON.origin` and an explicit server-side immutable set of authorized fully qualified origins (protocol, host, port).
- Engineers MUST NOT derive the expected `rpId` or `origin` dynamically from untrusted client request headers (e.g., `Host`, `X-Forwarded-Host`, `Referer`, or payload parameters).
- Services MUST verify that `clientDataJSON.type` strictly equals `'webauthn.get'` during authentication assertion and reject unexpected operations.
- Engineers MUST ensure client-side `navigator.credentials.get({ mediation: 'conditional' })` specifies an exact `rpId` and does not rely on default browser origin fallback across federated contexts.
- Verification routines MUST compute SHA-256 hash matching over the raw `clientDataJSON` bytes directly, preserving octet ordering to prevent JSON parsing normalization bypasses.
- Server validation logic MUST reject assertions where the registered credential's domain scope conflicts with the active session tenant or subdomain context.

## Bad vs Good Implementations
### Server-Side WebAuthn Conditional Assertion Verification

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Deriving the expected origin and rpId dynamically from incoming request headers or using loose suffix matching (endsWith) allows an attacker who controls an untrusted subdomain to harvest or replay passkey credentials across federated origins via conditional autofill.
```typescript
import { Request, Response } from 'express';

interface WebAuthnAssertionRequest {
  id: string;
  clientDataJSON: string;
  authenticatorData: string;
  signature: string;
}

export async function verifyAssertionBad(req: Request, res: Response) {
  const { clientDataJSON, authenticatorData, signature } = req.body as WebAuthnAssertionRequest;
  const clientData = JSON.parse(Buffer.from(clientDataJSON, 'base64url').toString('utf8'));

  // VULNERABILITY: Deriving origin and rpId from client headers allows subdomain spoofing
  // and cross-origin credential harvesting across federated tenants.
  const requestOrigin = req.headers.origin as string;
  if (clientData.origin.endsWith('example.com') && clientData.origin === requestOrigin) {
    // Insecure: Accepts any untrusted subdomain (e.g., attacker-tenant.example.com)
    const rpId = req.hostname;
    return res.status(200).json({ status: 'ok', rpId, verified: true });
  }

  return res.status(401).json({ error: 'Origin verification failed' });
}
```

#### Production Standard (Correct)
> **Standard**: Strictly checks the clientDataJSON origin against an immutable server-side allowlist, rejects unexpected types, and verifies the rpIdHash within authenticatorData against the canonical RP ID using timing-safe comparisons.
```typescript
import { Request, Response } from 'express';
import crypto from 'node:crypto';

// Explicit immutable allowlist of canonical origins per environment
const CANONICAL_ORIGINS: ReadonlySet<string> = new Set([
  'https://login.example.com',
  'https://app.example.com'
]);

const CANONICAL_RP_ID = 'example.com';

interface WebAuthnAssertionRequest {
  id: string;
  rawId: string;
  clientDataJSON: string;
  authenticatorData: string;
  signature: string;
}

export async function verifyAssertionGood(req: Request, res: Response) {
  const { clientDataJSON, authenticatorData, signature } = req.body as WebAuthnAssertionRequest;
  
  const rawClientDataBuffer = Buffer.from(clientDataJSON, 'base64url');
  const clientData = JSON.parse(rawClientDataBuffer.toString('utf8'));

  // Invariant 1: Type must strictly match webauthn.get
  if (clientData.type !== 'webauthn.get') {
    return res.status(400).json({ error: 'Invalid assertion ceremony type' });
  }

  // Invariant 2: Origin must strictly match an immutable canonical origin
  if (!CANONICAL_ORIGINS.has(clientData.origin)) {
    return res.status(403).json({ error: 'Origin binding validation rejected: unauthorized origin' });
  }

  // Invariant 3: Verify rpIdHash matches SHA-256 of canonical RP ID
  const rawAuthData = Buffer.from(authenticatorData, 'base64url');
  const rpIdHashFromAuthData = rawAuthData.subarray(0, 32);
  const expectedRpIdHash = crypto.createHash('sha256').update(CANONICAL_RP_ID).digest();

  if (!crypto.timingSafeEqual(rpIdHashFromAuthData, expectedRpIdHash)) {
    return res.status(403).json({ error: 'Relying Party ID hash mismatch' });
  }

  // Complete cryptographic signature validation using canonical rpId...
  return res.status(200).json({ status: 'ok', verified: true });
}
```

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: Strict RP ID and Origin Cross-Binding Guardrail for WebAuthn Conditional Mediation

Strict RP ID and Origin Cross-Binding Guardrail for WebAuthn Conditional Mediation defines an industrial-grade behavioral standard for security engineering. Enforces cryptographic and structural validation of Relying Party ID (rpId) and clientDataJSON origin during WebAuthn conditional mediation (autofill). Eliminates cross-origin credential harvesting, subdomain credential confusion, and federated origin spoofing by requiring explicit origin allowlisting and canonical RP ID matching on server-side 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: Permissive Subdomain Wildcarding or Unchecked clientDataJSON Origin in Conditional WebAuthn Verification 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 DriftPermissive Subdomain Wildcarding or Unchecked clientDataJSON Origin in Conditional WebAuthn VerificationCritical
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

Engineers MUST ALWAYS enforce strict equality between `clientDataJSON.origin` and an explicit server-side immutable set of authorized fully qualified origins (protocol, host, port).

Engineers MUST ALWAYS enforce strict equality between `clientDataJSON.origin` and an explicit server-side immutable set of authorized fully qualified origins (protocol, host, port).

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 NOT derive the expected `rpId` or `origin` dynamically from untrusted client request headers (e.g., `Host`, `X-Forwarded-Host`, `Referer`, or payload parameters).

Engineers MUST NOT derive the expected `rpId` or `origin` dynamically from untrusted client request headers (e.g., `Host`, `X-Forwarded-Host`, `Referer`, or payload parameters).

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

Services MUST verify that `clientDataJSON.type` strictly equals `'webauthn.get'` during authentication assertion and reject unexpected operations.

Services MUST verify that `clientDataJSON.type` strictly equals `'webauthn.get'` during authentication assertion and reject unexpected operations.

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

Engineers MUST ensure client-side `navigator.credentials.get({ mediation

Engineers MUST ensure client-side `navigator.credentials.get({ mediation: 'conditional' })` specifies an exact `rpId` and does not rely on default browser origin fallback across federated contexts.

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 compute SHA-256 hash matching over the raw `clientDataJSON` bytes directly, preserving octet ordering to prevent JSON parsing normalization bypasses.

Verification routines MUST compute SHA-256 hash matching over the raw `clientDataJSON` bytes directly, preserving octet ordering to prevent JSON parsing normalization bypasses.

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

Server validation logic MUST reject assertions where the registered credential's domain scope conflicts with the active session tenant or subdomain context.

Server validation logic MUST reject assertions where the registered credential's domain scope conflicts with the active session tenant or subdomain context.

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 Strict RP ID and Origin Cross-Binding Guardrail for WebAuthn Conditional Mediation critical for AI coding assistants?

Enforces cryptographic and structural validation of Relying Party ID (rpId) and clientDataJSON origin during WebAuthn conditional mediation (autofill). Eliminates cross-origin credential harvesting, subdomain credential confusion, and federated origin spoofing by requiring explicit origin allowlisting and canonical RP ID matching on server-side 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 (Permissive Subdomain Wildcarding or Unchecked clientDataJSON Origin in Conditional WebAuthn Verification) 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

Strict