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

WebAuthn Level 3 PRF Symmetric Key Derivation & Zero-Knowledge Vault Standard

Enforces strict cryptographic invariants when deriving zero-knowledge symmetric vault keys using the WebAuthn Level 3 PRF (Pseudo-Random Function) extension. Requires HKDF domain separation, enforces non-extractable CryptoKey handles, and forbids transmission of PRF material to Relying Parties.

Prohibited Anti-Pattern: Exfiltrating PRF output to Relying Party backends or directly using raw PRF buffers as cipher keys without HKDF expansion.

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: WebAuthn Level 3 PRF Symmetric Key Derivation & Zero-Knowledge Vault Standard - Enforces strict cryptographic invariants when deriving zero-knowledge symmetric vault keys using the WebAuthn Level 3 PRF (Pseudo-Random Function) extension. Requires HKDF domain separation, enforces non-extractable CryptoKey handles, and forbids transmission of PRF material to Relying Parties.
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-level3-prf-symmetric-key-derivation-standard"
---

# WebAuthn Level 3 PRF Symmetric Key Derivation & Zero-Knowledge Vault Standard

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Exfiltrating PRF output to Relying Party backends or directly using raw PRF buffers as cipher keys without HKDF expansion.

## System Constraints
You are a Principal Security Architect enforcing the WebAuthn Level 3 PRF Symmetric Key Derivation Standard. You must mandate zero-knowledge hardware-backed key derivation invariants, strictly prohibiting raw PRF usage without HKDF expansion, preventing key material exfiltration to the Relying Party, and enforcing non-extractable in-memory cryptographic handles.

## Strict Guidelines
- Engineers MUST ALWAYS verify authenticator PRF support during credential registration by checking (registrationCredential.getClientExtensionResults().prf?.supported === true) before persisting credential metadata.
- Engineers MUST ALWAYS derive final symmetric cipher keys using HKDF (RFC 5869) via SubtleCrypto.deriveKey, specifying an application-specific domain-separated 'info' parameter (e.g., 'vault-encryption-v1') and a cryptographic salt.
- Engineers MUST NOT use raw authenticator PRF output buffers (eval.first or eval.second) directly as symmetric encryption keys (e.g., AES-GCM or ChaCha20-Poly1305).
- Engineers MUST NOT transmit raw PRF output, intermediate HKDF materials, or derived symmetric keys to the Relying Party (backend server) or any network endpoint.
- Code MUST import and derive symmetric keys with { extractable: false } in SubtleCrypto to prevent memory-dump attacks and cross-site scripting (XSS) key extraction.
- Code MUST zeroize intermediate typed arrays (e.g., prfRawResult.fill(0)) immediately after importing into the Web Crypto API subsystem.
- Components NEVER store PRF-derived keys in unencrypted client-side persistence mechanisms such as localStorage, IndexedDB, or sessionStorage.

## Bad vs Good Implementations
### WebAuthn Level 3 PRF Key Derivation with HKDF and Zeroization

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Directly imports the PRF raw buffer as an AES key without domain-separated HKDF, creates an extractable key vulnerable to XSS exfiltration, and leaks the hardware-derived secret across the network to the backend server, violating zero-knowledge architecture.
```typescript
// Anti-pattern: Direct raw PRF usage, extractable keys, and exfiltrating secrets to server
export async function unlockVaultInsecure(credentialId: Uint8Array, salt: Uint8Array) {
  const credential = (await navigator.credentials.get({
    publicKey: {
      challenge: crypto.getRandomValues(new Uint8Array(32)),
      allowCredentials: [{ id: credentialId, type: 'public-key' }],
      extensions: {
        prf: {
          eval: { first: salt }
        }
      }
    }
  })) as PublicKeyCredential;

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

  if (!rawPrfKey) {
    throw new Error('PRF execution failed or not supported');
  }

  // FLAW 1: Direct use of PRF output as AES key without HKDF domain separation
  // FLAW 2: extractable: true allows key extraction via heap inspection or XSS
  const aesKey = await crypto.subtle.importKey(
    'raw',
    rawPrfKey,
    { name: 'AES-GCM' },
    true,
    ['encrypt', 'decrypt']
  );

  // FLAW 3: Exfiltrating the raw PRF key or credential to the backend
  await fetch('/api/vault/session', {
    method: 'POST',
    body: JSON.stringify({ prfKey: Array.from(new Uint8Array(rawPrfKey)) })
  });

  return aesKey;
}
```

#### Production Standard (Correct)
> **Standard**: Uses HKDF to perform proper domain separation over the authenticator PRF entropy, configures all WebCrypto instances with extractable: false to prevent memory scraping, strictly zeroizes intermediate byte arrays in a finally block, and prevents any network exfiltration of client vault secrets.
```typescript
// Production standard: HKDF domain separation, non-extractable handle, zeroization
const DOMAIN_SEPARATOR_INFO = new TextEncoder().encode('vault-storage-encryption-v1');

export async function unlockVaultSecure(
  credentialId: Uint8Array,
  hkdfSalt: Uint8Array
): Promise<CryptoKey> {
  const credential = (await navigator.credentials.get({
    publicKey: {
      challenge: crypto.getRandomValues(new Uint8Array(32)),
      allowCredentials: [{ id: credentialId, type: 'public-key' }],
      extensions: {
        prf: {
          eval: { first: hkdfSalt }
        }
      }
    }
  })) as PublicKeyCredential | null;

  if (!credential) {
    throw new Error('WebAuthn assertion failed or cancelled');
  }

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

  if (!rawPrfBuffer) {
    throw new Error('Authenticator did not return PRF evaluation results');
  }

  const rawPrfBytes = new Uint8Array(rawPrfBuffer);

  try {
    // 1. Ingest PRF output as raw key material for HKDF derivation
    const prfKeyMaterial = await crypto.subtle.importKey(
      'raw',
      rawPrfBytes,
      { name: 'HKDF' },
      false, // non-extractable
      ['deriveKey']
    );

    // 2. Derive cryptographically domain-separated AES-256-GCM vault key
    const vaultKey = await crypto.subtle.deriveKey(
      {
        name: 'HKDF',
        hash: 'SHA-256',
        salt: hkdfSalt,
        info: DOMAIN_SEPARATOR_INFO
      },
      prfKeyMaterial,
      { name: 'AES-GCM', length: 256 },
      false, // non-extractable: cannot be read by JS runtime or XSS
      ['encrypt', 'decrypt']
    );

    return vaultKey;
  } finally {
    // 3. Guaranteed zeroization of intermediate raw PRF memory
    rawPrfBytes.fill(0);
  }
}
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: WebAuthn Level 3 PRF Symmetric Key Derivation & Zero-Knowledge Vault Standard

WebAuthn Level 3 PRF Symmetric Key Derivation & Zero-Knowledge Vault Standard defines an industrial-grade behavioral standard for security engineering. Enforces strict cryptographic invariants when deriving zero-knowledge symmetric vault keys using the WebAuthn Level 3 PRF (Pseudo-Random Function) extension. Requires HKDF domain separation, enforces non-extractable CryptoKey handles, and forbids transmission of PRF material to Relying Parties. 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 backends or directly using raw PRF buffers as cipher keys without HKDF expansion. 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 backends or directly using raw PRF buffers as cipher keys without HKDF expansion.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 authenticator PRF support during credential registration by checking (registrationCredential.getClientExtensionResults().prf?.supported === true) before persisting credential metadata.

Engineers MUST ALWAYS verify authenticator PRF support during credential registration by checking (registrationCredential.getClientExtensionResults().prf?.supported === true) before persisting credential metadata.

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 derive final symmetric cipher keys using HKDF (RFC 5869) via SubtleCrypto.deriveKey, specifying an application-specific domain-separated 'info' parameter (e.g., 'vault-encryption-v1') and a cryptographic salt.

Engineers MUST ALWAYS derive final symmetric cipher keys using HKDF (RFC 5869) via SubtleCrypto.deriveKey, specifying an application-specific domain-separated 'info' parameter (e.g., 'vault-encryption-v1') and a cryptographic salt.

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 use raw authenticator PRF output buffers (eval.first or eval.second) directly as symmetric encryption keys (e.g., AES-GCM or ChaCha20-Poly1305).

Engineers MUST NOT use raw authenticator PRF output buffers (eval.first or eval.second) directly as symmetric encryption keys (e.g., AES-GCM or ChaCha20-Poly1305).

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 NOT transmit raw PRF output, intermediate HKDF materials, or derived symmetric keys to the Relying Party (backend server) or any network endpoint.

Engineers MUST NOT transmit raw PRF output, intermediate HKDF materials, or derived symmetric keys to the Relying Party (backend server) or any network endpoint.

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 import and derive symmetric keys with { extractable

Code MUST import and derive symmetric keys with { extractable: false } in SubtleCrypto to prevent memory-dump attacks and cross-site scripting (XSS) key extraction.

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

Code MUST zeroize intermediate typed arrays (e.g., prfRawResult.fill(0)) immediately after importing into the Web Crypto API subsystem.

Code MUST zeroize intermediate typed arrays (e.g., prfRawResult.fill(0)) immediately after importing into the Web Crypto API subsystem.

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

Components NEVER store PRF-derived keys in unencrypted client-side persistence mechanisms such as localStorage, IndexedDB, or sessionStorage.

Components NEVER store PRF-derived keys in unencrypted client-side persistence mechanisms such as localStorage, IndexedDB, or sessionStorage.

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

Enforces strict cryptographic invariants when deriving zero-knowledge symmetric vault keys using the WebAuthn Level 3 PRF (Pseudo-Random Function) extension. Requires HKDF domain separation, enforces non-extractable CryptoKey handles, and forbids transmission of PRF material to Relying Parties. 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 backends or directly using raw PRF buffers as cipher keys without HKDF expansion.) 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