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

Mandatory Memory Fencing and Immediate Zeroization for WebAuthn PRF Secrets

Enforces deterministic client-side memory scrubbing and scope isolation for raw cryptographic key material derived via WebAuthn PRF (Pseudo-Random Function) extensions. Requires in-place zeroization of typed arrays immediately post-derivation within strict try-finally blocks to prevent FIDO2 hardware-derived keys from lingering across the V8 garbage-collected heap. Mandates importing ephemeral symmetric keys as non-extractable WebCrypto handles before scrubbing the underlying buffers.

Prohibited Anti-Pattern: Leaking Raw WebAuthn PRF Outputs into Heap Memory via Immutable Strings and Unzeroed Buffers

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Mandatory Memory Fencing and Immediate Zeroization for WebAuthn PRF Secrets - Enforces deterministic client-side memory scrubbing and scope isolation for raw cryptographic key material derived via WebAuthn PRF (Pseudo-Random Function) extensions. Requires in-place zeroization of typed arrays immediately post-derivation within strict try-finally blocks to prevent FIDO2 hardware-derived keys from lingering across the V8 garbage-collected heap. Mandates importing ephemeral symmetric keys as non-extractable WebCrypto handles before scrubbing the underlying buffers.
globs: src/crypto/**/*.{ts,tsx}, src/auth/**/*.{ts,tsx}, src/services/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/webauthn-prf-memory-fence-production-standard"
---

# Mandatory Memory Fencing and Immediate Zeroization for WebAuthn PRF Secrets

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Leaking Raw WebAuthn PRF Outputs into Heap Memory via Immutable Strings and Unzeroed Buffers

## System Constraints
You are a Principal Security Architect enforcing zero-trust cryptographic invariants in client-side TypeScript. You MUST reject any WebAuthn PRF handling that converts raw derived secret buffers into immutable JavaScript strings, caches raw PRF output in persistent module-level state, or fails to scrub intermediate ArrayBuffers in a deterministic try-finally block. Mandate non-extractable CryptoKey derivation and explicit in-place buffer zeroization.

## Strict Guidelines
- Engineers MUST ALWAYS wrap all raw WebAuthn PRF output buffers (e.g., results from `authenticationExtensionsClientOutputs.prf.results`) in a strict `try...finally` block.
- Engineers MUST ALWAYS scrub raw PRF outputs and intermediate key derivation buffers in the `finally` block using `crypto.getRandomValues(buffer)` or `buffer.fill(0)` immediately after use.
- Engineers MUST NOT convert raw PRF outputs or derived key material to JavaScript strings (such as base64 or hex) which cannot be deterministically garbage-collected or wiped from memory.
- Code SHOULD import raw PRF material into WebCrypto `CryptoKey` instances with `extractable: false` as quickly as possible, fencing the raw bytes from application logic.
- Services MUST ensure that hardware-derived PRF salt buffers and evaluated seeds are scoped exclusively to transient function execution frames and never saved in persistent objects, stores, or closures.
- Components NEVER accept raw hardware PRF secret buffers as props or state; only cryptographically derived opaque session handles or non-extractable CryptoKeys may cross boundary layers.

## Bad vs Good Implementations
### WebAuthn PRF Output Handling and In-Place Memory Scrubbing

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: The code converts raw hardware-derived PRF secrets into an immutable JavaScript string, leaks it across multiple heap allocations, marks the resulting CryptoKey as extractable, and performs no zeroization on the raw ArrayBuffer.
```typescript
export async function deriveKeyFromPrf(assertion: PublicKeyCredential): Promise<CryptoKey> {
  const extensionOutputs = assertion.getClientExtensionResults();
  // CRITICAL SECURITY FLAW: Converting raw hardware PRF output to a string
  // interned in the V8 heap, making zeroization impossible.
  const rawPrfBuffer = extensionOutputs.prf?.results?.first;
  if (!rawPrfBuffer) {
    throw new Error('PRF extension evaluation failed');
  }
  
  const hexSecret = Array.from(new Uint8Array(rawPrfBuffer))
    .map(b => b.toString(16).padStart(2, '0'))
    .join('');
  
  // Raw secret exposed to GC heap; persists indefinitely
  const rawKey = new TextEncoder().encode(hexSecret);
  return await crypto.subtle.importKey(
    'raw',
    rawKey,
    { name: 'AES-GCM' },
    true,
    ['encrypt', 'decrypt']
  );
}
```

#### Production Standard (Correct)
> **Standard**: Wraps the raw PRF ArrayBuffer in a strict try-finally block, imports it as a non-extractable CryptoKey, and immediately overwrites the memory buffer with cryptographic randomness and zeros in the finally clause, ensuring the secret never lingers in heap memory.
```typescript
export async function deriveKeyFromPrf(assertion: PublicKeyCredential): Promise<CryptoKey> {
  const extensionOutputs = assertion.getClientExtensionResults();
  const prfResults = extensionOutputs.prf?.results?.first;
  if (!(prfResults instanceof ArrayBuffer)) {
    throw new Error('PRF extension evaluation returned invalid or empty buffer');
  }

  // Create transient view over the buffer
  const prfView = new Uint8Array(prfResults);
  
  try {
    // Import immediately as non-extractable opaque handle
    return await crypto.subtle.importKey(
      'raw',
      prfView,
      { name: 'HKDF' },
      false, // non-extractable invariant
      ['deriveKey']
    );
  } finally {
    // Deterministic memory fence: Overwrite with CSPRNG noise, then zeroize
    crypto.getRandomValues(prfView);
    prfView.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: Mandatory Memory Fencing and Immediate Zeroization for WebAuthn PRF Secrets

Mandatory Memory Fencing and Immediate Zeroization for WebAuthn PRF Secrets defines an industrial-grade behavioral standard for security engineering. Enforces deterministic client-side memory scrubbing and scope isolation for raw cryptographic key material derived via WebAuthn PRF (Pseudo-Random Function) extensions. Requires in-place zeroization of typed arrays immediately post-derivation within strict try-finally blocks to prevent FIDO2 hardware-derived keys from lingering across the V8 garbage-collected heap. Mandates importing ephemeral symmetric keys as non-extractable WebCrypto handles before scrubbing the underlying buffers. 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: Leaking Raw WebAuthn PRF Outputs into Heap Memory via Immutable Strings and Unzeroed Buffers 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 DriftLeaking Raw WebAuthn PRF Outputs into Heap Memory via Immutable Strings and Unzeroed BuffersCritical
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 wrap all raw WebAuthn PRF output buffers (e.g., results from `authenticationExtensionsClientOutputs.prf.results`) in a strict `try...finally` block.

Engineers MUST ALWAYS wrap all raw WebAuthn PRF output buffers (e.g., results from `authenticationExtensionsClientOutputs.prf.results`) in a strict `try...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 ALWAYS scrub raw PRF outputs and intermediate key derivation buffers in the `finally` block using `crypto.getRandomValues(buffer)` or `buffer.fill(0)` immediately after use.

Engineers MUST ALWAYS scrub raw PRF outputs and intermediate key derivation buffers in the `finally` block using `crypto.getRandomValues(buffer)` or `buffer.fill(0)` immediately after use.

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 convert raw PRF outputs or derived key material to JavaScript strings (such as base64 or hex) which cannot be deterministically garbage-collected or wiped from memory.

Engineers MUST NOT convert raw PRF outputs or derived key material to JavaScript strings (such as base64 or hex) which cannot be deterministically garbage-collected or wiped from 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.
4

Code SHOULD import raw PRF material into WebCrypto `CryptoKey` instances with `extractable

Code SHOULD import raw PRF material into WebCrypto `CryptoKey` instances with `extractable: false` as quickly as possible, fencing the raw bytes from application logic.

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

Services MUST ensure that hardware-derived PRF salt buffers and evaluated seeds are scoped exclusively to transient function execution frames and never saved in persistent objects, stores, or closures.

Services MUST ensure that hardware-derived PRF salt buffers and evaluated seeds are scoped exclusively to transient function execution frames and never saved in persistent objects, stores, or closures.

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

Components NEVER accept raw hardware PRF secret buffers as props or state

Components NEVER accept raw hardware PRF secret buffers as props or state; only cryptographically derived opaque session handles or non-extractable CryptoKeys may cross boundary layers.

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 Mandatory Memory Fencing and Immediate Zeroization for WebAuthn PRF Secrets critical for AI coding assistants?

Enforces deterministic client-side memory scrubbing and scope isolation for raw cryptographic key material derived via WebAuthn PRF (Pseudo-Random Function) extensions. Requires in-place zeroization of typed arrays immediately post-derivation within strict try-finally blocks to prevent FIDO2 hardware-derived keys from lingering across the V8 garbage-collected heap. Mandates importing ephemeral symmetric keys as non-extractable WebCrypto handles before scrubbing the underlying buffers. 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 (Leaking Raw WebAuthn PRF Outputs into Heap Memory via Immutable Strings and Unzeroed Buffers) 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

Mandatory