This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
securitycritical PriorityID: passkey-sync-provider-downgrade-invariant

Passkey Sync-Provider Downgrade & Cryptographic Recovery Invariant

Enforces strict cryptographic step-up verification when WebAuthn credentials transition between multi-device synchronized states and unmanaged single-device states. Prevents account takeovers caused by credential cloning, sync-provider desynchronization, and unauthorized recovery downgrades by validating authenticator backup flags and requiring dual-rooted verification before binding changes.

Prohibited Anti-Pattern: Silently accepting passkey assertion state drift or falling back to weak recovery channels when sync flags mutate

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Passkey Sync-Provider Downgrade & Cryptographic Recovery Invariant - Enforces strict cryptographic step-up verification when WebAuthn credentials transition between multi-device synchronized states and unmanaged single-device states. Prevents account takeovers caused by credential cloning, sync-provider desynchronization, and unauthorized recovery downgrades by validating authenticator backup flags and requiring dual-rooted verification before binding changes.
globs: src/auth/**/*.{ts,tsx}, src/services/auth/**/*.{ts,tsx}, src/server/webauthn/**/*.{ts,tsx}, src/api/auth/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/passkey-sync-provider-downgrade-invariant"
---

# Passkey Sync-Provider Downgrade & Cryptographic Recovery Invariant

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Silently accepting passkey assertion state drift or falling back to weak recovery channels when sync flags mutate

## System Constraints
You are a Principal Security Architect enforcing the Passkey Sync-Provider Downgrade & Recovery Invariant. You must reject any authentication or recovery pipeline that allows credential state mutation, platform sync-provider detachment, or authenticator data flag downgrades (BE/BS flags) without mandatory cryptographic step-up verification against a verified secondary root of trust.

## Strict Guidelines
- Engineers MUST ALWAYS verify both `backupEligibility` (BE) and `backupState` (BS) bits within parsed `authenticatorData` against stored credential metadata during assertion verification.
- Engineers MUST NOT allow fallback to non-cryptographic authentication channels (SMS, email magic links, static security questions) when an unexpected passkey sync downgrade is detected.
- Services MUST mandate a cryptographic step-up challenge (such as cross-device WebAuthn re-assertion with User Verification = 1 or an enrolled hardware FIDO2 key) whenever a credential previously registered as synchronized (BE=1, BS=1) is asserted from an unmanaged or local-only state (BS=0).
- Services MUST immediately quarantine sessions and emit an audit event if the AAGUID indicates an unexpected platform transition without prior cryptographically signed device-enrollment consent.
- Components NEVER allow client-side assertion parameters to mutate stored credential sync state without explicit backend verification of raw attestation and user verification flags.

## Bad vs Good Implementations
### WebAuthn Assertion Backup State & Sync Downgrade Verification

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: The code validates basic signature and counter parameters but fails to parse or enforce WebAuthn flags (`backupEligibility` and `backupState`). An attacker asserting an unmanaged or cloned passkey on a rogue device transitions from managed sync to unmanaged state undetected, granting elevated access without required step-up verification.
```typescript
import type { AuthenticationResponseJSON } from '@simplewebauthn/types';
import { verifyAuthenticationResponse } from '@simplewebauthn/server';

interface StoredPasskey {
  credentialID: string;
  publicKey: Uint8Array;
  counter: number;
  transports?: string[];
}

export async function verifyAssertionAndHandleRecovery(
  response: AuthenticationResponseJSON,
  expectedChallenge: string,
  passkey: StoredPasskey
) {
  const verification = await verifyAuthenticationResponse({
    response,
    expectedChallenge,
    expectedOrigin: 'https://auth.example.com',
    expectedRPID: 'example.com',
    authenticator: {
      credentialID: passkey.credentialID,
      credentialPublicKey: passkey.publicKey,
      counter: passkey.counter,
    },
  });

  if (!verification.verified) {
    throw new Error('Authentication failed');
  }

  // VULNERABILITY: Blindly updates counter without inspecting authenticatorData flags.
  // If a multi-device synced passkey was extracted and asserted as an unmanaged local credential,
  // or if backup flags changed, the system ignores the downgrade and permits elevated access.
  passkey.counter = verification.authenticationInfo.newCounter;
  return { success: true, sessionTier: 'elevated' };
}
```

#### Production Standard (Correct)
> **Standard**: The good implementation verifies user verification, inspects `credentialDeviceType` and `backupStatus` from the parsed authenticator data, and explicitly asserts the invariant: a credential previously stored as synced cannot transition to an unmanaged state without triggering a mandatory cryptographic step-up verification challenge.
```typescript
import type { AuthenticationResponseJSON } from '@simplewebauthn/types';
import { verifyAuthenticationResponse } from '@simplewebauthn/server';

interface StoredPasskey {
  credentialID: string;
  publicKey: Uint8Array;
  counter: number;
  isBackedUp: boolean;
  backupEligible: boolean;
  aaguid: string;
}

export class PasskeySyncDowngradeError extends Error {
  constructor(message: string) {
    super(message);
    this.name = 'PasskeySyncDowngradeError';
  }
}

export async function verifyAssertionAndHandleRecovery(
  response: AuthenticationResponseJSON,
  expectedChallenge: string,
  passkey: StoredPasskey
): Promise<{ success: boolean; requiresStepUp: boolean }> {
  const verification = await verifyAuthenticationResponse({
    response,
    expectedChallenge,
    expectedOrigin: 'https://auth.example.com',
    expectedRPID: 'example.com',
    authenticator: {
      credentialID: passkey.credentialID,
      credentialPublicKey: passkey.publicKey,
      counter: passkey.counter,
    },
    requireUserVerification: true,
  });

  if (!verification.verified || !verification.authenticationInfo) {
    throw new Error('WebAuthn assertion verification failed');
  }

  const { credentialDeviceType, backupStatus, newCounter } = verification.authenticationInfo;
  const isCurrentlyBackedUp = backupStatus === true;
  const isCurrentlyMultiDevice = credentialDeviceType === 'multiDevice';

  // INVARIANT: Detect state downgrade from synchronized cloud state to unmanaged local state
  const wasSynced = passkey.backupEligible && passkey.isBackedUp;
  const isDowngraded = wasSynced && (!isCurrentlyBackedUp || !isCurrentlyMultiDevice);

  if (isDowngraded) {
    // Suspend full access; mandate cryptographic step-up verification before state update
    return {
      success: true,
      requiresStepUp: true,
    };
  }

  // Update verified cryptographic state only when invariants are satisfied
  passkey.counter = newCounter;
  passkey.isBackedUp = isCurrentlyBackedUp;
  passkey.backupEligible = isCurrentlyMultiDevice;

  return {
    success: true,
    requiresStepUp: false,
  };
}
```

Recommended MCP Servers (mcp-serverlist.com)

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

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Passkey Sync-Provider Downgrade & Cryptographic Recovery Invariant

Passkey Sync-Provider Downgrade & Cryptographic Recovery Invariant defines an industrial-grade behavioral standard for security engineering. Enforces strict cryptographic step-up verification when WebAuthn credentials transition between multi-device synchronized states and unmanaged single-device states. Prevents account takeovers caused by credential cloning, sync-provider desynchronization, and unauthorized recovery downgrades by validating authenticator backup flags and requiring dual-rooted verification before binding changes. 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: Silently accepting passkey assertion state drift or falling back to weak recovery channels when sync flags mutate 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 DriftSilently accepting passkey assertion state drift or falling back to weak recovery channels when sync flags mutateCritical
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 both `backupEligibility` (BE) and `backupState` (BS) bits within parsed `authenticatorData` against stored credential metadata during assertion verification.

Engineers MUST ALWAYS verify both `backupEligibility` (BE) and `backupState` (BS) bits within parsed `authenticatorData` against stored credential metadata during assertion verification.

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 allow fallback to non-cryptographic authentication channels (SMS, email magic links, static security questions) when an unexpected passkey sync downgrade is detected.

Engineers MUST NOT allow fallback to non-cryptographic authentication channels (SMS, email magic links, static security questions) when an unexpected passkey sync downgrade is detected.

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 mandate a cryptographic step-up challenge (such as cross-device WebAuthn re-assertion with User Verification = 1 or an enrolled hardware FIDO2 key) whenever a credential previously registered as synchronized (BE=1, BS=1) is asserted from an unmanaged or local-only state (BS=0).

Services MUST mandate a cryptographic step-up challenge (such as cross-device WebAuthn re-assertion with User Verification = 1 or an enrolled hardware FIDO2 key) whenever a credential previously registered as synchronized (BE=1, BS=1) is asserted from an unmanaged or local-only state (BS=0).

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 immediately quarantine sessions and emit an audit event if the AAGUID indicates an unexpected platform transition without prior cryptographically signed device-enrollment consent.

Services MUST immediately quarantine sessions and emit an audit event if the AAGUID indicates an unexpected platform transition without prior cryptographically signed device-enrollment consent.

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 allow client-side assertion parameters to mutate stored credential sync state without explicit backend verification of raw attestation and user verification flags.

Components NEVER allow client-side assertion parameters to mutate stored credential sync state without explicit backend verification of raw attestation and user verification flags.

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 Passkey Sync-Provider Downgrade & Cryptographic Recovery Invariant critical for AI coding assistants?

Enforces strict cryptographic step-up verification when WebAuthn credentials transition between multi-device synchronized states and unmanaged single-device states. Prevents account takeovers caused by credential cloning, sync-provider desynchronization, and unauthorized recovery downgrades by validating authenticator backup flags and requiring dual-rooted verification before binding changes. 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 (Silently accepting passkey assertion state drift or falling back to weak recovery channels when sync flags mutate) 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

Passkey