This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
securitycritical PriorityID: webauthn-prf-zk-client-key-derivation-standard

WebAuthn PRF Extension Zero-Knowledge Client Key Derivation Standard

Mandates strict zero-knowledge client-side key derivation from WebAuthn PRF (pseudo-random function) extension outputs. Enforces fail-closed validation for non-supporting authenticators, memory zeroization of raw PRF output buffers, non-extractable WebCrypto key imports, and explicit exclusion of cryptographic derivation artifacts from relying party network payloads.

Prohibited Anti-Pattern: Exfiltrating PRF Output to Relying Party Servers or Storing Extractable Master Key Material in Persistent Client Storage

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: WebAuthn PRF Extension Zero-Knowledge Client Key Derivation Standard - Mandates strict zero-knowledge client-side key derivation from WebAuthn PRF (pseudo-random function) extension outputs. Enforces fail-closed validation for non-supporting authenticators, memory zeroization of raw PRF output buffers, non-extractable WebCrypto key imports, and explicit exclusion of cryptographic derivation artifacts from relying party network payloads.
globs: src/**/*.{ts,tsx}, lib/**/*.{ts,tsx}, packages/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/webauthn-prf-zk-client-key-derivation-standard"
---

# WebAuthn PRF Extension Zero-Knowledge Client Key Derivation Standard

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Exfiltrating PRF Output to Relying Party Servers or Storing Extractable Master Key Material in Persistent Client Storage

## System Constraints
You are a Principal Security Architect enforcing the WebAuthn PRF Extension Zero-Knowledge Client Key Derivation Standard. You must strictly forbid any design that passes raw PRF outputs, master derivation secrets, or intermediate cryptographic seeds to backend relying party (RP) servers. Enforce hardware-backed key derivation via WebCrypto HKDF, non-extractable key parameters, fail-closed PRF capability checks, and ephemeral memory zeroization of all intermediate buffers.

## Strict Guidelines
- Engineers MUST ALWAYS verify that clientExtensionResults.prf?.enabled or results.first exists before proceeding; the system MUST fail closed if the authenticator lacks PRF hardware support.
- Engineers MUST NOT transmit the raw PRF evaluation output (results.first or results.second) or derived key material to any backend API or relying party server under any circumstances.
- Engineers MUST ALWAYS use the raw PRF output strictly as input key material (IKM) to standard HKDF (RFC 5869) using crypto.subtle.deriveKey with explicit domain-separation context (info string) before deriving operational keys (e.g., AES-GCM-256).
- Engineers MUST ALWAYS import derived cryptographic keys with extractable: false to prevent memory scraping, browser extension tampering, or accidental serialization.
- Code MUST explicitly wipe transient Uint8Array buffers containing raw PRF evaluations by calling .fill(0) immediately after key derivation.
- Engineers MUST NEVER persist raw PRF seeds, master decryption keys, or unencrypted IKM in localStorage, sessionStorage, IndexedDB, or cookies.
- Authentication payloads sent to the Relying Party MUST ONLY contain standard credential assertion structures (id, rawId, response: { clientDataJSON, authenticatorData, signature, userHandle }); PRF output MUST be decoupled entirely before network transmission.

## Bad vs Good Implementations
### Client-Side Zero-Knowledge Decryption Key Derivation via WebAuthn PRF

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Transmits raw PRF output to the relying party backend, destroying zero-knowledge architecture. Persists master secret material in unencrypted localStorage, and imports the raw output directly into an extractable AES-GCM key without HKDF domain separation, opening the client to memory extraction and replay attacks.
```typescript
export async function authenticateAndDeriveKey(credentialId: Uint8Array, challenge: Uint8Array) {
  const credential = (await navigator.credentials.get({
    publicKey: {
      challenge,
      allowCredentials: [{ id: credentialId, type: 'public-key' }],
      extensions: {
        prf: {
          eval: {
            first: new TextEncoder().encode('global-decryption-salt-1234')
          }
        }
      }
    }
  })) as PublicKeyCredential;

  const extResults = credential.getClientExtensionResults();
  const rawPrf = extResults.prf?.results?.first;

  // CRITICAL SECURITY VIOLATIONS:
  // 1. Sending raw PRF output to server in authentication verification request.
  // 2. Storing raw master secret in localStorage.
  // 3. Storing extractable key directly without HKDF domain separation.
  await fetch('/api/auth/verify', {
    method: 'POST',
    body: JSON.stringify({ credential, rawPrf: Array.from(new Uint8Array(rawPrf!)) })
  });

  localStorage.setItem('raw_prf_secret', JSON.stringify(Array.from(new Uint8Array(rawPrf!))));

  return crypto.subtle.importKey(
    'raw',
    rawPrf!,
    { name: 'AES-GCM' },
    true, // Extractable allows malicious scripts to dump key
    ['decrypt', 'encrypt']
  );
}
```

#### Production Standard (Correct)
> **Standard**: Enforces zero-knowledge guarantees: raw PRF outputs are never sent to the server. The PRF result is imported into WebCrypto with non-extractable handles, processed via HKDF with contextual domain separation, strictly fails closed if PRF is unavailable, and wipes intermediate memory buffers via `.fill(0)`.
```typescript
export async function authenticateAndDeriveKey(
  credentialId: Uint8Array,
  challenge: Uint8Array,
  prfSalt: Uint8Array
): Promise<CryptoKey> {
  const credential = (await navigator.credentials.get({
    publicKey: {
      challenge,
      allowCredentials: [{ id: credentialId, type: 'public-key' }],
      extensions: {
        prf: {
          eval: {
            first: prfSalt
          }
        }
      }
    }
  })) as PublicKeyCredential | null;

  if (!credential) {
    throw new Error('Credential assertion failed or aborted.');
  }

  const extResults = credential.getClientExtensionResults();
  const rawPrfBuffer = extResults.prf?.results?.first;

  if (!rawPrfBuffer) {
    // Fail closed if authenticator lacks PRF extension support
    throw new Error('Hardware authenticator does not support the WebAuthn PRF extension.');
  }

  const prfBytes = new Uint8Array(rawPrfBuffer);

  try {
    // Step 1: Import raw PRF output as HKDF key material (non-extractable)
    const ikmKey = await crypto.subtle.importKey(
      'raw',
      prfBytes,
      'HKDF',
      false,
      ['deriveKey']
    );

    // Step 2: Derive domain-separated non-extractable AES-GCM data encryption key
    const info = new TextEncoder().encode('ZK-Vault-Client-Data-Encryption-v1');
    const derivedKey = await crypto.subtle.deriveKey(
      {
        name: 'HKDF',
        hash: 'SHA-256',
        salt: prfSalt,
        info
      },
      ikmKey,
      { name: 'AES-GCM', length: 256 },
      false, // Non-extractable to prevent scraping
      ['encrypt', 'decrypt']
    );

    // Step 3: Send strictly standard assertion payload to server without PRF artifacts
    const authPayload = {
      id: credential.id,
      rawId: Array.from(new Uint8Array(credential.rawId)),
      response: {
        clientDataJSON: Array.from(new Uint8Array(credential.response.clientDataJSON)),
        authenticatorData: Array.from(new Uint8Array((credential.response as AuthenticatorAssertionResponse).authenticatorData)),
        signature: Array.from(new Uint8Array((credential.response as AuthenticatorAssertionResponse).signature)),
        userHandle: (credential.response as AuthenticatorAssertionResponse).userHandle
          ? Array.from(new Uint8Array((credential.response as AuthenticatorAssertionResponse).userHandle!))
          : null
      }
    };

    await fetch('/api/auth/verify', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(authPayload)
    });

    return derivedKey;
  } finally {
    // Step 4: Ephemeral memory zeroization of raw intermediate buffers
    prfBytes.fill(0);
  }
}
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: WebAuthn PRF Extension Zero-Knowledge Client Key Derivation Standard

WebAuthn PRF Extension Zero-Knowledge Client Key Derivation Standard defines an industrial-grade behavioral standard for security engineering. Mandates strict zero-knowledge client-side key derivation from WebAuthn PRF (pseudo-random function) extension outputs. Enforces fail-closed validation for non-supporting authenticators, memory zeroization of raw PRF output buffers, non-extractable WebCrypto key imports, and explicit exclusion of cryptographic derivation artifacts from relying party network payloads. 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: Exfiltrating PRF Output to Relying Party Servers or Storing Extractable Master Key Material in Persistent Client Storage 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 DriftExfiltrating PRF Output to Relying Party Servers or Storing Extractable Master Key Material in Persistent Client StorageCritical
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 that clientExtensionResults.prf?.enabled or results.first exists before proceeding

Engineers MUST ALWAYS verify that clientExtensionResults.prf?.enabled or results.first exists before proceeding; the system MUST fail closed if the authenticator lacks PRF hardware support.

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 transmit the raw PRF evaluation output (results.first or results.second) or derived key material to any backend API or relying party server under any circumstances.

Engineers MUST NOT transmit the raw PRF evaluation output (results.first or results.second) or derived key material to any backend API or relying party server under any circumstances.

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 ALWAYS use the raw PRF output strictly as input key material (IKM) to standard HKDF (RFC 5869) using crypto.subtle.deriveKey with explicit domain-separation context (info string) before deriving operational keys (e.g., AES-GCM-256).

Engineers MUST ALWAYS use the raw PRF output strictly as input key material (IKM) to standard HKDF (RFC 5869) using crypto.subtle.deriveKey with explicit domain-separation context (info string) before deriving operational keys (e.g., AES-GCM-256).

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 ALWAYS import derived cryptographic keys with extractable

Engineers MUST ALWAYS import derived cryptographic keys with extractable: false to prevent memory scraping, browser extension tampering, or accidental serialization.

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

Code MUST explicitly wipe transient Uint8Array buffers containing raw PRF evaluations by calling .fill(0) immediately after key derivation.

Code MUST explicitly wipe transient Uint8Array buffers containing raw PRF evaluations by calling .fill(0) immediately after key derivation.

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

Engineers MUST NEVER persist raw PRF seeds, master decryption keys, or unencrypted IKM in localStorage, sessionStorage, IndexedDB, or cookies.

Engineers MUST NEVER persist raw PRF seeds, master decryption keys, or unencrypted IKM in localStorage, sessionStorage, IndexedDB, or cookies.

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.
7

Authentication payloads sent to the Relying Party MUST ONLY contain standard credential assertion structures (id, rawId, response

Authentication payloads sent to the Relying Party MUST ONLY contain standard credential assertion structures (id, rawId, response: { clientDataJSON, authenticatorData, signature, userHandle }); PRF output MUST be decoupled entirely before network transmission.

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 PRF Extension Zero-Knowledge Client Key Derivation Standard critical for AI coding assistants?

Mandates strict zero-knowledge client-side key derivation from WebAuthn PRF (pseudo-random function) extension outputs. Enforces fail-closed validation for non-supporting authenticators, memory zeroization of raw PRF output buffers, non-extractable WebCrypto key imports, and explicit exclusion of cryptographic derivation artifacts from relying party network payloads. 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 (Exfiltrating PRF Output to Relying Party Servers or Storing Extractable Master Key Material in Persistent Client Storage) 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