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

WebAuthn PRF Deterministic Key Derivation and Zeroization Invariant

Enforces strict memory zeroization and non-extractable cryptographic key lifecycles when using the WebAuthn PRF (pseudo-random function) extension for zero-knowledge client decryption. Guarantees that raw hardware-derived PRF seeds and intermediate key material are wiped from typed array buffers in finally blocks to prevent heap memory dump extraction.

Prohibited Anti-Pattern: Retaining raw WebAuthn PRF output in garbage-collected string or buffer memory without deterministic zeroization

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: WebAuthn PRF Deterministic Key Derivation and Zeroization Invariant - Enforces strict memory zeroization and non-extractable cryptographic key lifecycles when using the WebAuthn PRF (pseudo-random function) extension for zero-knowledge client decryption. Guarantees that raw hardware-derived PRF seeds and intermediate key material are wiped from typed array buffers in finally blocks to prevent heap memory dump extraction.
globs: src/**/*.{ts,tsx,js,mjs}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/webauthn-prf-key-derivation-zeroization-standard"
---

# WebAuthn PRF Deterministic Key Derivation and Zeroization Invariant

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Retaining raw WebAuthn PRF output in garbage-collected string or buffer memory without deterministic zeroization

## System Constraints
You are a Principal Security Architect enforcing the WebAuthn PRF Deterministic Key-Derivation Zeroization Standard. WebAuthn PRF extensions yield raw hardware-rooted symmetric seeds that can decrypt zero-knowledge payloads. You must enforce that raw entropy buffers are strictly isolated in mutable TypedArrays (Uint8Array), never transformed into immutable primitives (strings, base64, hex), imported into non-extractable WebCrypto CryptoKey instances, and deterministically zeroed out in structured `finally` blocks immediately following cryptographic operations.

## Strict Guidelines
- Engineers MUST ALWAYS isolate raw PRF evaluation buffers (`results.prf.results.first`) in mutable `Uint8Array` containers and overwrite them with zeroes (`typedArray.fill(0)`) within a guaranteed `finally` block.
- Engineers MUST NEVER convert raw PRF outputs or derived key material into immutable JavaScript string formats (e.g., UTF-8, base64, hex), as immutable strings cannot be scrubbed from V8 heap memory.
- Code MUST import the intermediate PRF seed into Web Crypto `SubtleCrypto.importKey` with `extractable: false` immediately upon derivation, zeroing out the source byte buffer directly afterwards.
- Services MUST NOT persist WebAuthn PRF symmetric keys across asynchronous user interactions; ephemeral keys must be derived on-demand, utilized for decryption, and discarded.
- Components NEVER expose raw PRF outputs to logging frameworks, error traces, telemetry collectors, or state management stores (Redux, Zustand, Pinia).

## Bad vs Good Implementations
### Vulnerable PRF Derivation and String Leakage vs Secure Ephemeral Zeroization

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Raw PRF output is converted into an immutable string (secretHex) which persists arbitrarily in V8 garbage collector memory. The imported key is marked as extractable, and the input raw PRF buffer is never overwritten with zeroes, exposing the zero-knowledge master secret to memory dump side-channels.
```typescript
export async function decryptVaultWithWebAuthn(assertion: PublicKeyCredential, ciphertext: Uint8Array, iv: Uint8Array): Promise<ArrayBuffer> {
  const extensionResults = assertion.getClientExtensionResults();
  // VULNERABLE: Direct access without buffer protection and converting secret to string
  const rawPrf = extensionResults.prf?.results?.first as ArrayBuffer;
  const secretHex = Array.from(new Uint8Array(rawPrf)).map(b => b.toString(16).padStart(2, '0')).join('');
  
  // Secret string persists indefinitely in V8 garbage collector memory
  const keyMaterial = await crypto.subtle.importKey(
    'raw',
    rawPrf,
    'HKDF',
    true, // VULNERABLE: Extractable key
    ['deriveKey']
  );

  const derivedKey = await crypto.subtle.deriveKey(
    { name: 'HKDF', hash: 'SHA-256', salt: new Uint8Array(32), info: new TextEncoder().encode('vault') },
    keyMaterial,
    { name: 'AES-GCM', length: 256 },
    true,
    ['decrypt']
  );

  return crypto.subtle.decrypt({ name: 'AES-GCM', iv }, derivedKey, ciphertext);
}
```

#### Production Standard (Correct)
> **Standard**: The secret seed is wrapped in a mutable `Uint8Array`, imported into Web Crypto with `extractable: false`, and deterministically zeroed using `.fill(0)` inside a `finally` block, neutralizing core dump and process memory attacks.
```typescript
export async function decryptVaultWithWebAuthn(assertion: PublicKeyCredential, ciphertext: Uint8Array, iv: Uint8Array): Promise<ArrayBuffer> {
  const extensionResults = assertion.getClientExtensionResults();
  const rawPrf = extensionResults.prf?.results?.first;
  if (!rawPrf) {
    throw new Error('WebAuthn PRF extension output not available');
  }

  // SECURE: Wrap raw PRF into mutable typed array for explicit lifecycle management
  const secretSeed = new Uint8Array(rawPrf.slice(0));
  const salt = new Uint8Array(32); // Hardware-specific salt
  
  try {
    const hkdfKey = await crypto.subtle.importKey(
      'raw',
      secretSeed,
      'HKDF',
      false, // SECURE: Non-extractable prevents dumping via JS runtime
      ['deriveKey']
    );

    const decryptionKey = await crypto.subtle.deriveKey(
      {
        name: 'HKDF',
        hash: 'SHA-256',
        salt,
        info: new TextEncoder().encode('client-vault-v1')
      },
      hkdfKey,
      { name: 'AES-GCM', length: 256 },
      false, // SECURE: Derived key is non-extractable
      ['decrypt']
    );

    return await crypto.subtle.decrypt(
      { name: 'AES-GCM', iv },
      decryptionKey,
      ciphertext
    );
  } finally {
    // SECURE: Mandatory deterministic zeroization of memory buffers
    secretSeed.fill(0);
    new Uint8Array(rawPrf).fill(0);
    salt.fill(0);
  }
}
```

Recommended MCP Servers (mcp-serverlist.com)

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

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: WebAuthn PRF Deterministic Key Derivation and Zeroization Invariant

WebAuthn PRF Deterministic Key Derivation and Zeroization Invariant defines an industrial-grade behavioral standard for security engineering. Enforces strict memory zeroization and non-extractable cryptographic key lifecycles when using the WebAuthn PRF (pseudo-random function) extension for zero-knowledge client decryption. Guarantees that raw hardware-derived PRF seeds and intermediate key material are wiped from typed array buffers in finally blocks to prevent heap memory dump extraction. 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: Retaining raw WebAuthn PRF output in garbage-collected string or buffer memory without deterministic zeroization 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 DriftRetaining raw WebAuthn PRF output in garbage-collected string or buffer memory without deterministic zeroizationCritical
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 isolate raw PRF evaluation buffers (`results.prf.results.first`) in mutable `Uint8Array` containers and overwrite them with zeroes (`typedArray.fill(0)`) within a guaranteed `finally` block.

Engineers MUST ALWAYS isolate raw PRF evaluation buffers (`results.prf.results.first`) in mutable `Uint8Array` containers and overwrite them with zeroes (`typedArray.fill(0)`) within a guaranteed `finally` block.

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 NEVER convert raw PRF outputs or derived key material into immutable JavaScript string formats (e.g., UTF-8, base64, hex), as immutable strings cannot be scrubbed from V8 heap memory.

Engineers MUST NEVER convert raw PRF outputs or derived key material into immutable JavaScript string formats (e.g., UTF-8, base64, hex), as immutable strings cannot be scrubbed from V8 heap memory.

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

Code MUST import the intermediate PRF seed into Web Crypto `SubtleCrypto.importKey` with `extractable

Code MUST import the intermediate PRF seed into Web Crypto `SubtleCrypto.importKey` with `extractable: false` immediately upon derivation, zeroing out the source byte buffer directly afterwards.

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 NOT persist WebAuthn PRF symmetric keys across asynchronous user interactions

Services MUST NOT persist WebAuthn PRF symmetric keys across asynchronous user interactions; ephemeral keys must be derived on-demand, utilized for decryption, and discarded.

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 expose raw PRF outputs to logging frameworks, error traces, telemetry collectors, or state management stores (Redux, Zustand, Pinia).

Components NEVER expose raw PRF outputs to logging frameworks, error traces, telemetry collectors, or state management stores (Redux, Zustand, Pinia).

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 Deterministic Key Derivation and Zeroization Invariant critical for AI coding assistants?

Enforces strict memory zeroization and non-extractable cryptographic key lifecycles when using the WebAuthn PRF (pseudo-random function) extension for zero-knowledge client decryption. Guarantees that raw hardware-derived PRF seeds and intermediate key material are wiped from typed array buffers in finally blocks to prevent heap memory dump extraction. 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 (Retaining raw WebAuthn PRF output in garbage-collected string or buffer memory without deterministic zeroization) 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