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

Passkey WebAuthn Conditional UI Credential Mediation & Session Isolation Guardrail

Enforces strict lifecycle management, AbortController cancellation, challenge scoping, and userHandle validation for WebAuthn Conditional UI requests. Prevents autofill phishing, cross-origin ambient credential hijacking, and concurrent session collision by separating ambient autofill mediation from explicit platform and cross-device authentication flows.

Prohibited Anti-Pattern: Unaborted Conditional UI Mediation with Permissive User Handle Binding and Challenge Replay

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Passkey WebAuthn Conditional UI Credential Mediation & Session Isolation Guardrail - Enforces strict lifecycle management, AbortController cancellation, challenge scoping, and userHandle validation for WebAuthn Conditional UI requests. Prevents autofill phishing, cross-origin ambient credential hijacking, and concurrent session collision by separating ambient autofill mediation from explicit platform and cross-device authentication flows.
globs: src/**/*.{ts,tsx}, lib/**/*.{ts,tsx}, app/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/passkey-conditional-ui-credential-mediation-guardrail"
---

# Passkey WebAuthn Conditional UI Credential Mediation & Session Isolation Guardrail

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Unaborted Conditional UI Mediation with Permissive User Handle Binding and Challenge Replay

## System Constraints
You are a Principal Software Architect enforcing production security standards for Passkey WebAuthn Conditional UI (autofill mediation). You must ensure all ambient credential requests are guarded by feature detection, isolated via deterministic AbortController instances, bound to ephemeral server-side challenges, and strictly separated from explicit modal and cross-device flows to prevent session collision and identity substitution attacks.

## Strict Guidelines
- Engineers MUST ALWAYS verify window.PublicKeyCredential?.isConditionalMediationAvailable?.() before invoking navigator.credentials.get({ mediation: 'conditional' }).
- Engineers MUST ALWAYS manage an explicit AbortController instance for ambient Conditional UI requests and abort active ambient mediation before triggering explicit modal authentication.
- Engineers MUST NEVER reuse challenges across conditional UI and explicit modal flows; every mediation request must bind to a unique, single-use, session-scoped challenge.
- Services MUST validate that the assertion's userHandle strictly matches the target session identity during step-up or re-authentication flows, rejecting mismatched authenticated handles.
- Components NEVER store ambient credential resolution results directly into shared application state without atomic validation and backend cryptographic verification.

## Bad vs Good Implementations
### Ambient Passkey Authentication with Abort Lifecycle and Session Isolation

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Fails to check if conditional mediation is supported, omits an AbortSignal leading to un-cancellable ambient loops and race conditions with explicit user actions, reuses static challenges vulnerable to replay, and accepts arbitrary userHandles into the session without validation.
```typescript
import { useState } from 'react';

export function usePasskeyLogin() {
  const [loading, setLoading] = useState(false);

  async function startConditionalLogin() {
    // VULNERABLE: No feature detection, no AbortController, shared static challenge
    setLoading(true);
    const assertion = await (navigator.credentials.get as any)({
      mediation: 'conditional',
      publicKey: {
        challenge: new Uint8Array([1, 2, 3, 4]),
        timeout: 60000,
        userVerification: 'preferred',
      },
    });

    if (assertion) {
      // Directly setting session without validating userHandle or separating flows
      await fetch('/api/auth/session', {
        method: 'POST',
        body: JSON.stringify({ id: assertion.id }),
      });
    }
    setLoading(false);
  }

  return { startConditionalLogin, loading };
}
```

#### Production Standard (Correct)
> **Standard**: Properly performs runtime conditional mediation capability detection, manages an AbortController across component lifecycles, safely ignores programmatic AbortErrors, validates returned userHandle against expected session context to prevent session collision, and exposes an abort trigger for explicit modal transitions.
```typescript
import { useEffect, useRef, useCallback } from 'react';

interface ConditionalAuthOptions {
  challenge: string;
  rpId: string;
  expectedUserId?: string;
  onSuccess: (credential: PublicKeyCredential) => Promise<void>;
  onError: (error: Error) => void;
}

export function useConditionalPasskey({
  challenge,
  rpId,
  expectedUserId,
  onSuccess,
  onError,
}: ConditionalAuthOptions) {
  const abortControllerRef = useRef<AbortController | null>(null);

  const cancelAmbientRequest = useCallback(() => {
    if (abortControllerRef.current && !abortControllerRef.current.signal.aborted) {
      abortControllerRef.current.abort('Conditional mediation cancelled for explicit flow');
      abortControllerRef.current = null;
    }
  }, []);

  useEffect(() => {
    let isMounted = true;

    async function initConditionalAuth() {
      const isAvailable =
        typeof window !== 'undefined' &&
        window.PublicKeyCredential &&
        typeof window.PublicKeyCredential.isConditionalMediationAvailable === 'function' &&
        (await window.PublicKeyCredential.isConditionalMediationAvailable());

      if (!isAvailable || !isMounted) return;

      cancelAmbientRequest();
      const controller = new AbortController();
      abortControllerRef.current = controller;

      try {
        const challengeBuffer = Uint8Array.from(atob(challenge), (c) => c.charCodeAt(0));
        const credential = (await navigator.credentials.get({
          mediation: 'conditional',
          signal: controller.signal,
          publicKey: {
            challenge: challengeBuffer,
            rpId,
            userVerification: 'preferred',
            timeout: 120000,
          },
        })) as PublicKeyCredential | null;

        if (!credential || !isMounted) return;

        const response = credential.response as AuthenticatorAssertionResponse;
        if (expectedUserId && response.userHandle) {
          const returnedUserId = new TextDecoder().decode(response.userHandle);
          if (returnedUserId !== expectedUserId) {
            throw new Error('Credential identity mismatch: userHandle does not match expected identity');
          }
        }

        await onSuccess(credential);
      } catch (err: unknown) {
        if (err instanceof DOMException && err.name === 'AbortError') {
          return;
        }
        if (isMounted) {
          onError(err instanceof Error ? err : new Error(String(err)));
        }
      }
    }

    initConditionalAuth();

    return () => {
      isMounted = false;
      cancelAmbientRequest();
    };
  }, [challenge, rpId, expectedUserId, onSuccess, onError, cancelAmbientRequest]);

  return { cancelAmbientRequest };
}
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Passkey WebAuthn Conditional UI Credential Mediation & Session Isolation Guardrail

Passkey WebAuthn Conditional UI Credential Mediation & Session Isolation Guardrail defines an industrial-grade behavioral standard for security engineering. Enforces strict lifecycle management, AbortController cancellation, challenge scoping, and userHandle validation for WebAuthn Conditional UI requests. Prevents autofill phishing, cross-origin ambient credential hijacking, and concurrent session collision by separating ambient autofill mediation from explicit platform and cross-device authentication flows. 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: Unaborted Conditional UI Mediation with Permissive User Handle Binding and Challenge Replay 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 DriftUnaborted Conditional UI Mediation with Permissive User Handle Binding and Challenge ReplayCritical
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 window.PublicKeyCredential?.isConditionalMediationAvailable?.() before invoking navigator.credentials.get({ mediation

Engineers MUST ALWAYS verify window.PublicKeyCredential?.isConditionalMediationAvailable?.() before invoking navigator.credentials.get({ mediation: 'conditional' }).

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 manage an explicit AbortController instance for ambient Conditional UI requests and abort active ambient mediation before triggering explicit modal authentication.

Engineers MUST ALWAYS manage an explicit AbortController instance for ambient Conditional UI requests and abort active ambient mediation before triggering explicit modal 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.
3

Engineers MUST NEVER reuse challenges across conditional UI and explicit modal flows

Engineers MUST NEVER reuse challenges across conditional UI and explicit modal flows; every mediation request must bind to a unique, single-use, session-scoped 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.
4

Services MUST validate that the assertion's userHandle strictly matches the target session identity during step-up or re-authentication flows, rejecting mismatched authenticated handles.

Services MUST validate that the assertion's userHandle strictly matches the target session identity during step-up or re-authentication flows, rejecting mismatched authenticated handles.

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 store ambient credential resolution results directly into shared application state without atomic validation and backend cryptographic verification.

Components NEVER store ambient credential resolution results directly into shared application state without atomic validation and backend cryptographic 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.
Technical Questions & Answers

Frequently Asked Technical Questions

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

Q:Why is Passkey WebAuthn Conditional UI Credential Mediation & Session Isolation Guardrail critical for AI coding assistants?

Enforces strict lifecycle management, AbortController cancellation, challenge scoping, and userHandle validation for WebAuthn Conditional UI requests. Prevents autofill phishing, cross-origin ambient credential hijacking, and concurrent session collision by separating ambient autofill mediation from explicit platform and cross-device authentication flows. 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 (Unaborted Conditional UI Mediation with Permissive User Handle Binding and Challenge Replay) 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