This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
securitycritical PriorityID: webauthn-l3-passkey-device-binding-attestation-standard

WebAuthn Level 3 Synced Passkey Device-Binding and Attestation Guardrail

Enforces strict WebAuthn Level 3 cryptographic validation for passkey registration and authentication. Mandates explicit inspection of AuthenticatorData flags (Backup Eligibility, Backup State, User Verification), Device Public Key (DPK) extensions, and exact origin binding to neutralize credential-sync hijacking and multi-device replay attacks.

Prohibited Anti-Pattern: Accepting unverified authenticator flags, missing DPK attestation, and applying rigid signature counters to multi-device synced passkeys.

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: WebAuthn Level 3 Synced Passkey Device-Binding and Attestation Guardrail - Enforces strict WebAuthn Level 3 cryptographic validation for passkey registration and authentication. Mandates explicit inspection of AuthenticatorData flags (Backup Eligibility, Backup State, User Verification), Device Public Key (DPK) extensions, and exact origin binding to neutralize credential-sync hijacking and multi-device replay attacks.
globs: src/**/auth/**/*.{ts,tsx}, src/**/webauthn/**/*.{ts,tsx}, src/**/identity/**/*.{ts,tsx}, src/**/passkey/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/webauthn-l3-passkey-device-binding-attestation-standard"
---

# WebAuthn Level 3 Synced Passkey Device-Binding and Attestation Guardrail

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Accepting unverified authenticator flags, missing DPK attestation, and applying rigid signature counters to multi-device synced passkeys.

## System Constraints
You are a Principal Engineer enforcing WebAuthn Level 3 Synced Passkey Device-Binding Attestation Standard. Mandate invariants that verify cryptographic origin matching, challenge single-use lifecycles, explicit AuthenticatorData bitflag parsing (UP, UV, BE, BS), and Device Public Key (DPK) extensions. Reject any WebAuthn implementation that applies legacy single-device counter assumptions to multi-device credentials or bypasses attestation trust validation.

## Strict Guidelines
- Engineers MUST ALWAYS verify the parsed clientDataJSON `origin` matches the exact RP origin byte-for-byte, and ensure `crossOrigin` is explicitly `false` or absent when cross-origin requests are prohibited.
- Engineers MUST evaluate the `flags.backupEligibility` (BE) and `flags.backupState` (BS) in `authenticatorData`: high-assurance high-risk scopes MUST reject credentials with `backupEligibility=true` unless accompanied by a verified Device Public Key (`devicePublicKey`) extension.
- Engineers MUST NOT apply legacy monotonic `signCount > previousSignCount` checks indiscriminately to synced passkeys where `backupEligibility=true`; synced credentials legitimately report static or non-monotonic signature counters across distinct synced devices.
- Services MUST enforce cryptographic single-use challenges stored in a cryptographically secure, ephemeral, server-side store with a strictly enforced TTL (maximum 120 seconds).
- Components NEVER accept `clientExtensionResults` without cryptographically verifying the extension payload against the raw `authenticatorData` extension bytes.

## Bad vs Good Implementations
### WebAuthn L3 Assertion Verification with Synced Flag & Origin Validation

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Fails to inspect Backup Eligibility (BE) and Backup State (BS) flags, leading to false-positive lockout or security compromise. Monotonic counter checks break valid multi-device sync passkeys, and clientDataJSON origin validation lacks strict transport and crossOrigin enforcement.
```typescript
import { Request, Response } from 'express';
import { verifyAuthenticationResponse } from '@simplewebauthn/server';

export async function verifyPasskeyAuth(req: Request, res: Response) {
  const { credential, expectedChallenge } = req.body;

  // VULNERABILITY: Blind verification without origin strictness, missing
  // crossOrigin check, and applying invalid monotonic signCount checks to synced passkeys.
  const verification = await verifyAuthenticationResponse({
    response: credential,
    expectedChallenge,
    expectedOrigin: 'https://example.com',
    expectedRPID: 'example.com',
    authenticator: {
      credentialPublicKey: Buffer.from(req.body.storedPublicKey, 'base64'),
      credentialID: Buffer.from(credential.id, 'base64'),
      counter: req.body.storedCounter,
    },
  });

  if (verification.verified) {
    // Naive signCount update will falsely reject synced passkeys from secondary devices
    if (verification.authenticationInfo.newCounter <= req.body.storedCounter) {
      return res.status(401).json({ error: 'Possible cloned authenticator detected' });
    }
    return res.status(200).json({ success: true });
  }
  return res.status(400).json({ error: 'Failed' });
}
```

#### Production Standard (Correct)
> **Standard**: Implements full WebAuthn L3 flag inspection: validates `userVerified`, correctly branches counter handling based on `backupEligibility`, strictly validates the challenge lifecycle, and asserts exact RP origin.
```typescript
import { Request, Response } from 'express';
import { verifyAuthenticationResponse, VerifiedAuthenticationResponse } from '@simplewebauthn/server';
import { consumeChallenge, getStoredCredential, updateCredentialUsage } from './security/passkey-store';

const EXPECTED_RP_ID = 'auth.enterprise.domain';
const EXPECTED_ORIGIN = 'https://auth.enterprise.domain';
const MAX_CHALLENGE_TTL_MS = 60_000;

export async function verifyPasskeyAuth(req: Request, res: Response): Promise<Response> {
  const { credential, sessionId } = req.body;

  // 1. Enforce single-use ephemeral challenge retrieval with cryptographic invalidation
  const challengeRecord = await consumeChallenge(sessionId);
  if (!challengeRecord || Date.now() - challengeRecord.createdAt > MAX_CHALLENGE_TTL_MS) {
    return res.status(401).json({ error: 'Expired or reused challenge nonce.' });
  }

  const storedCred = await getStoredCredential(credential.id);
  if (!storedCred) {
    return res.status(404).json({ error: 'Credential not registered.' });
  }

  let verification: VerifiedAuthenticationResponse;
  try {
    verification = await verifyAuthenticationResponse({
      response: credential,
      expectedChallenge: challengeRecord.challenge,
      expectedOrigin: EXPECTED_ORIGIN,
      expectedRPID: EXPECTED_RP_ID,
      authenticator: {
        credentialPublicKey: storedCred.publicKey,
        credentialID: storedCred.credentialID,
        counter: storedCred.counter,
        transports: storedCred.transports,
      },
      requireUserVerification: true,
    });
  } catch (error) {
    return res.status(401).json({ error: 'Cryptographic assertion validation failed.' });
  }

  const { authenticationInfo } = verification;
  const { flags, newCounter } = authenticationInfo;

  // 2. WebAuthn L3 Flag Validation: Enforce User Verification (UV)
  if (!flags.userVerified) {
    return res.status(403).json({ error: 'User verification (UV) flag required.' });
  }

  // 3. Authenticator Counter & Backup State Invariant Handling
  const isSyncedPasskey = flags.backupEligibility;

  if (isSyncedPasskey) {
    // Synced credentials (multi-device) do not maintain global monotonic counters across devices
    // Persist backup state to audit trail; do not fail on counter <= storedCred.counter unless counter > 0 is expected
    await updateCredentialUsage(storedCred.id, {
      counter: newCounter,
      backupState: flags.backupState,
      lastUsedAt: new Date(),
    });
  } else {
    // Device-bound passkey (hardware token / secure enclave single-device)
    if (storedCred.counter > 0 && newCounter <= storedCred.counter) {
      return res.status(403).json({ error: 'Cloned device-bound authenticator detected: invalid counter.' });
    }
    await updateCredentialUsage(storedCred.id, {
      counter: newCounter,
      backupState: false,
      lastUsedAt: new Date(),
    });
  }

  return res.status(200).json({ success: true, isSynced: isSyncedPasskey });
}
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: WebAuthn Level 3 Synced Passkey Device-Binding and Attestation Guardrail

WebAuthn Level 3 Synced Passkey Device-Binding and Attestation Guardrail defines an industrial-grade behavioral standard for security engineering. Enforces strict WebAuthn Level 3 cryptographic validation for passkey registration and authentication. Mandates explicit inspection of AuthenticatorData flags (Backup Eligibility, Backup State, User Verification), Device Public Key (DPK) extensions, and exact origin binding to neutralize credential-sync hijacking and multi-device replay attacks. 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: Accepting unverified authenticator flags, missing DPK attestation, and applying rigid signature counters to multi-device synced passkeys. 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 DriftAccepting unverified authenticator flags, missing DPK attestation, and applying rigid signature counters to multi-device synced passkeys.Critical
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 verify the parsed clientDataJSON `origin` matches the exact RP origin byte-for-byte, and ensure `crossOrigin` is explicitly `false` or absent when cross-origin requests are prohibited.

Engineers MUST ALWAYS verify the parsed clientDataJSON `origin` matches the exact RP origin byte-for-byte, and ensure `crossOrigin` is explicitly `false` or absent when cross-origin requests are prohibited.

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 evaluate the `flags.backupEligibility` (BE) and `flags.backupState` (BS) in `authenticatorData`

Engineers MUST evaluate the `flags.backupEligibility` (BE) and `flags.backupState` (BS) in `authenticatorData`: high-assurance high-risk scopes MUST reject credentials with `backupEligibility=true` unless accompanied by a verified Device Public Key (`devicePublicKey`) extension.

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 apply legacy monotonic `signCount > previousSignCount` checks indiscriminately to synced passkeys where `backupEligibility=true`

Engineers MUST NOT apply legacy monotonic `signCount > previousSignCount` checks indiscriminately to synced passkeys where `backupEligibility=true`; synced credentials legitimately report static or non-monotonic signature counters across distinct synced devices.

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 cryptographic single-use challenges stored in a cryptographically secure, ephemeral, server-side store with a strictly enforced TTL (maximum 120 seconds).

Services MUST enforce cryptographic single-use challenges stored in a cryptographically secure, ephemeral, server-side store with a strictly enforced TTL (maximum 120 seconds).

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

Components NEVER accept `clientExtensionResults` without cryptographically verifying the extension payload against the raw `authenticatorData` extension bytes.

Components NEVER accept `clientExtensionResults` without cryptographically verifying the extension payload against the raw `authenticatorData` extension bytes.

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 Level 3 Synced Passkey Device-Binding and Attestation Guardrail critical for AI coding assistants?

Enforces strict WebAuthn Level 3 cryptographic validation for passkey registration and authentication. Mandates explicit inspection of AuthenticatorData flags (Backup Eligibility, Backup State, User Verification), Device Public Key (DPK) extensions, and exact origin binding to neutralize credential-sync hijacking and multi-device replay attacks. 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 (Accepting unverified authenticator flags, missing DPK attestation, and applying rigid signature counters to multi-device synced passkeys.) 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