This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
securitycritical PriorityID: fido2-device-bound-origin-attestation-invariant

FIDO2 WebAuthn Canonical Origin & Discovery Attestation Invariant

Enforces cryptographic and exact validation of clientDataJSON origin strings against immutable server-side discovery manifests and canonical RP origin sets during FIDO2/WebAuthn ceremonies. Prevents adversary-in-the-middle (AiTM) reverse-proxy phishing and credential relay attacks by eliminating dynamic host header derivations, loose regexes, and unverified multi-tenant origin reflections.

Prohibited Anti-Pattern: Dynamic Host Derivation or Loose Origin Pattern Matching in WebAuthn Client Data Verification

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: FIDO2 WebAuthn Canonical Origin & Discovery Attestation Invariant - Enforces cryptographic and exact validation of clientDataJSON origin strings against immutable server-side discovery manifests and canonical RP origin sets during FIDO2/WebAuthn ceremonies. Prevents adversary-in-the-middle (AiTM) reverse-proxy phishing and credential relay attacks by eliminating dynamic host header derivations, loose regexes, and unverified multi-tenant origin reflections.
globs: **/auth/**/*.{ts,tsx,js,mjs}, **/webauthn/**/*.{ts,tsx,js,mjs}, **/identity/**/*.{ts,tsx,js,mjs}, **/api/auth/**
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/fido2-device-bound-origin-attestation-invariant"
---

# FIDO2 WebAuthn Canonical Origin & Discovery Attestation Invariant

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Dynamic Host Derivation or Loose Origin Pattern Matching in WebAuthn Client Data Verification

## System Constraints
You are a Principal Security Architect enforcing the FIDO2 Device-Bound Passkey Origin Attestation Invariant. You must reject any WebAuthn/FIDO2 implementation that dynamically resolves expected origins from unauthenticated HTTP request headers (such as Host or X-Forwarded-Host), employs partial or wildcard string matching on clientDataJSON.origin, or skips app-association discovery manifest verification for mobile clients. Require strict, constant-time exact canonical origin matching against compile-time or hardware-backed configurations.

## Strict Guidelines
- Engineers MUST ALWAYS validate clientDataJSON.origin against an immutable, strictly defined allowlist of canonical origins (e.g., https://auth.domain.com:443).
- Engineers MUST NOT dynamically construct expected WebAuthn origins from incoming request headers like Host, X-Forwarded-Host, or Referer.
- Engineers MUST NOT utilize loose pattern matching, substring checks (includes), or permissive regular expressions (endsWith('.domain.com')) to validate clientDataJSON.origin.
- Services MUST enforce that the clientDataJSON.type property matches the exact expected ceremony type ('webauthn.create' for registration, 'webauthn.get' for authentication).
- Services verifying native mobile passkey assertions MUST validate origins against authentic cryptographically anchored manifests (Android Digital Asset Links SHA-256 fingerprints or Apple App Site Association app IDs).
- Components NEVER accept insecure transport schemes; origins MUST explicitly require 'https://' scheme, except for isolated local development loopback bindings ('http://localhost' on exact verified ports).

## Bad vs Good Implementations
### FIDO2 Client Data Origin & Ceremony Validation

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Deriving the expected origin from HTTP Host/X-Forwarded-Host headers enables reverse-proxy phishing proxies (e.g., Evilginx) to proxy requests transparently and trick the server into validating the phishing origin. Furthermore, using String.prototype.includes or unanchored regular expressions permits attacker domains like 'https://attacker-example.com' to pass validation.
```typescript
import { Request, Response } from 'express';

interface WebAuthnAssertion {
  clientDataJSON: string; // base64url
}

export async function verifyAssertionBad(req: Request, res: Response) {
  const assertion: WebAuthnAssertion = req.body;
  const rawClientData = Buffer.from(assertion.clientDataJSON, 'base64url').toString('utf-8');
  const clientData = JSON.parse(rawClientData);

  // VULNERABLE: Derives expected origin dynamically from unauthenticated request header
  const requestHost = req.headers['host'] || req.headers['x-forwarded-host'];
  if (!clientData.origin.includes(requestHost)) {
    return res.status(403).json({ error: 'Origin mismatch' });
  }

  // VULNERABLE: Loose regex matching allows adversary domain e.g., 'attacker-example.com'
  if (!/example\.com$/.test(clientData.origin)) {
    return res.status(403).json({ error: 'Untrusted domain' });
  }

  return res.status(200).json({ status: 'authenticated' });
}
```

#### Production Standard (Correct)
> **Standard**: Enforces constant exact-match validation against an immutable canonical allowlist populated with verified web origins and app asset link key hashes. Completely eliminates reliance on untrusted HTTP request headers and rejects unexpected cross-origin assertions, rendering reverse-proxy phishing and relay attacks ineffective.
```typescript
import { Request, Response } from 'express';
import crypto from 'node:crypto';

interface ClientDataJSON {
  type: string;
  challenge: string;
  origin: string;
  crossOrigin?: boolean;
}

// Immutable canonical origin registry derived from strict environment configuration
const CANONICAL_ALLOWED_ORIGINS = new Set<string>([
  'https://login.company.com',
  'https://app.company.com',
  // Verified Android APK package signature hash
  'android:apk-key-hash:p3vQ01E53mK6bUvF5s9J3uT1lKk='
]);

const EXPECTED_CEREMONY_TYPE = 'webauthn.get';

export async function verifyAssertionGood(req: Request, res: Response) {
  const { clientDataJSON } = req.body as { clientDataJSON: string };

  if (!clientDataJSON || typeof clientDataJSON !== 'string') {
    return res.status(400).json({ error: 'Invalid clientDataJSON payload' });
  }

  const rawBuffer = Buffer.from(clientDataJSON, 'base64url');
  const parsedClientData: ClientDataJSON = JSON.parse(rawBuffer.toString('utf-8'));

  // 1. Strict ceremony type enforcement
  if (parsedClientData.type !== EXPECTED_CEREMONY_TYPE) {
    return res.status(400).json({ error: 'Ceremony type mismatch' });
  }

  // 2. Canonical exact matching against immutable allowlist
  if (!CANONICAL_ALLOWED_ORIGINS.has(parsedClientData.origin)) {
    return res.status(403).json({ error: 'Attestation failed: origin not authorized' });
  }

  // 3. Reject unexpected cross-origin context unless explicitly partitioned and verified
  if (parsedClientData.crossOrigin === true) {
    return res.status(403).json({ error: 'Unauthorized cross-origin WebAuthn ceremony' });
  }

  return res.status(200).json({ status: 'authenticated' });
}
```

Recommended MCP Servers (mcp-serverlist.com)

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

Architectural Specification & Invariant Rationale

Architectural Invariant Design: FIDO2 WebAuthn Canonical Origin & Discovery Attestation Invariant

FIDO2 WebAuthn Canonical Origin & Discovery Attestation Invariant defines an industrial-grade behavioral standard for security engineering. Enforces cryptographic and exact validation of clientDataJSON origin strings against immutable server-side discovery manifests and canonical RP origin sets during FIDO2/WebAuthn ceremonies. Prevents adversary-in-the-middle (AiTM) reverse-proxy phishing and credential relay attacks by eliminating dynamic host header derivations, loose regexes, and unverified multi-tenant origin reflections. 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: Dynamic Host Derivation or Loose Origin Pattern Matching in WebAuthn Client Data 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 DriftDynamic Host Derivation or Loose Origin Pattern Matching in WebAuthn Client Data 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 validate clientDataJSON.origin against an immutable, strictly defined allowlist of canonical origins (e.g., https

Engineers MUST ALWAYS validate clientDataJSON.origin against an immutable, strictly defined allowlist of canonical origins (e.g., https://auth.domain.com:443).

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 dynamically construct expected WebAuthn origins from incoming request headers like Host, X-Forwarded-Host, or Referer.

Engineers MUST NOT dynamically construct expected WebAuthn origins from incoming request headers like Host, X-Forwarded-Host, or Referer.

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 utilize loose pattern matching, substring checks (includes), or permissive regular expressions (endsWith('.domain.com')) to validate clientDataJSON.origin.

Engineers MUST NOT utilize loose pattern matching, substring checks (includes), or permissive regular expressions (endsWith('.domain.com')) to validate clientDataJSON.origin.

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

Services MUST enforce that the clientDataJSON.type property matches the exact expected ceremony type ('webauthn.create' for registration, 'webauthn.get' for authentication).

Services MUST enforce that the clientDataJSON.type property matches the exact expected ceremony type ('webauthn.create' for registration, 'webauthn.get' for authentication).

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

Services verifying native mobile passkey assertions MUST validate origins against authentic cryptographically anchored manifests (Android Digital Asset Links SHA-256 fingerprints or Apple App Site Association app IDs).

Services verifying native mobile passkey assertions MUST validate origins against authentic cryptographically anchored manifests (Android Digital Asset Links SHA-256 fingerprints or Apple App Site Association app IDs).

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 accept insecure transport schemes

Components NEVER accept insecure transport schemes; origins MUST explicitly require 'https://' scheme, except for isolated local development loopback bindings ('http://localhost' on exact verified ports).

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 FIDO2 WebAuthn Canonical Origin & Discovery Attestation Invariant critical for AI coding assistants?

Enforces cryptographic and exact validation of clientDataJSON origin strings against immutable server-side discovery manifests and canonical RP origin sets during FIDO2/WebAuthn ceremonies. Prevents adversary-in-the-middle (AiTM) reverse-proxy phishing and credential relay attacks by eliminating dynamic host header derivations, loose regexes, and unverified multi-tenant origin reflections. 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 (Dynamic Host Derivation or Loose Origin Pattern Matching in WebAuthn Client Data 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

FIDO2