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

WebAuthn PRF Extension Zero-Knowledge Key Derivation Invariant

Enforces strict cryptographic domain separation and client-side isolation when deriving symmetric keys via the WebAuthn PRF (pseudo-random function) extension. Guarantees that raw PRF outputs and derived symmetric encryption keys are non-extractable, zeroized immediately after initialization, and never exfiltrated to application backends, session storage, or telemetry streams.

Prohibited Anti-Pattern: Exposing Raw PRF Outputs to Backends or Storing Extractable Derived Symmetric Keys

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: WebAuthn PRF Extension Zero-Knowledge Key Derivation Invariant - Enforces strict cryptographic domain separation and client-side isolation when deriving symmetric keys via the WebAuthn PRF (pseudo-random function) extension. Guarantees that raw PRF outputs and derived symmetric encryption keys are non-extractable, zeroized immediately after initialization, and never exfiltrated to application backends, session storage, or telemetry streams.
globs: src/**/crypto/**/*.{ts,tsx}, src/**/auth/**/*.{ts,tsx}, src/**/services/**/*.{ts,tsx}, src/**/vault/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/webauthn-prf-zk-key-derivation-guardrail-webauthn-prf-ext-831"
---

# WebAuthn PRF Extension Zero-Knowledge Key Derivation Invariant

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Exposing Raw PRF Outputs to Backends or Storing Extractable Derived Symmetric Keys

## System Constraints
You are a Principal Cryptography and Application Security Architect enforcing the WebAuthn PRF Extension Zero-Knowledge Key Derivation Invariant. You must reject any implementation that serializes PRF output extensions to remote servers, marks derived WebCrypto keys as extractable, or uses raw PRF results directly as cipher keys without HKDF domain separation.

## Strict Guidelines
- Engineers MUST ALWAYS strip the `prf` extension output from the WebAuthn `AuthenticationCredential` before sending the assertion response to the backend server.
- Engineers MUST ALWAYS ingest the 32-byte raw PRF output directly into `crypto.subtle.importKey` as an ephemeral HKDF master key with `extractable: false`.
- Engineers MUST ALWAYS use HKDF (`HMAC-SHA-256`) with distinct, application-specific `info` and `salt` parameters to derive symmetric encryption keys (e.g., `AES-GCM-256`), ensuring strict domain separation.
- Engineers MUST NOT persist raw PRF results, intermediate keying material, or derived keys into `localStorage`, `sessionStorage`, `IndexedDB`, or cookies.
- Components NEVER expose derived `CryptoKey` handles to client telemetry, error trackers, or unprivileged UI state trees.
- Code SHOULD zeroize ephemeral `Uint8Array` memory buffers containing PRF inputs or outputs immediately after `crypto.subtle` key derivation.

## Bad vs Good Implementations
### Insecure: Transmitting Raw PRF to Backend and Storing Extractable Key

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: This pattern leaks the zero-knowledge secret to the backend, stores the raw key material in localStorage (vulnerable to XSS), skips HKDF domain separation, and sets `extractable: true`, allowing in-memory key compromise.
```typescript
async function authenticateAndDeriveKey(credentialRequestOptions: CredentialRequestOptions) {
  const credential = await navigator.credentials.get(credentialRequestOptions) as PublicKeyCredential;
  const extensionResults = credential.getClientExtensionResults();
  
  // CRITICAL SECURITY FLAW: Sending PRF output to the backend destroys zero-knowledge architecture
  await fetch('/api/auth/verify', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      credential,
      prfOutput: Array.from(new Uint8Array(extensionResults.prf?.results?.first || []))
    })
  });

  // INSECURE: Using PRF output directly as AES key without HKDF, with extractable: true
  const rawPrf = new Uint8Array(extensionResults.prf!.results!.first);
  const key = await crypto.subtle.importKey(
    'raw',
    rawPrf,
    { name: 'AES-GCM' },
    true, // extractable exposes key to XSS
    ['encrypt', 'decrypt']
  );
  localStorage.setItem('raw_key', JSON.stringify(Array.from(rawPrf)));
  return key;
}
```

#### Production Standard (Correct)
> **Standard**: The good implementation strips PRF outputs from server transport, imports raw PRF bytes into a non-extractable HKDF intermediate key, wipes the raw buffer with zeros, and derives a dedicated non-extractable AES-GCM-256 key with domain-separated info parameters.
```typescript
async function authenticateAndDeriveKey(
  credentialRequestOptions: CredentialRequestOptions,
  applicationSalt: Uint8Array,
  domainContext: string
): Promise<CryptoKey> {
  const credential = (await navigator.credentials.get(
    credentialRequestOptions
  )) as PublicKeyCredential | null;

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

  const extensionResults = credential.getClientExtensionResults();
  const prfResult = extensionResults.prf?.results?.first;
  if (!prfResult) {
    throw new Error('Authenticator did not return expected PRF output.');
  }

  // 1. Strip PRF extension results before transmitting assertion to backend
  const assertionForServer = {
    id: credential.id,
    rawId: Array.from(new Uint8Array(credential.rawId)),
    response: {
      authenticatorData: Array.from(new Uint8Array(credential.response.authenticatorData)),
      clientDataJSON: Array.from(new Uint8Array(credential.response.clientDataJSON)),
      signature: Array.from(new Uint8Array(credential.response.signature)),
      userHandle: credential.response.userHandle
        ? Array.from(new Uint8Array(credential.response.userHandle))
        : null
    },
    type: credential.type
  };

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

  // 2. Import raw PRF output into non-extractable HKDF master key
  const rawBuffer = new Uint8Array(prfResult);
  const hkdfKey = await crypto.subtle.importKey(
    'raw',
    rawBuffer,
    { name: 'HKDF' },
    false, // Master key material cannot be extracted
    ['deriveKey']
  );

  // 3. Zeroize memory immediately after importing to WebCrypto internal slot
  rawBuffer.fill(0);

  // 4. Derive isolated, non-extractable symmetric key using domain separation
  const derivedCipherKey = await crypto.subtle.deriveKey(
    {
      name: 'HKDF',
      hash: 'SHA-256',
      salt: applicationSalt,
      info: new TextEncoder().encode(`zk-vault-encryption:v1:${domainContext}`)
    },
    hkdfKey,
    { name: 'AES-GCM', length: 256 },
    false, // Non-extractable derived key
    ['encrypt', 'decrypt']
  );

  return derivedCipherKey;
}
```

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 Extension Zero-Knowledge Key Derivation Invariant

WebAuthn PRF Extension Zero-Knowledge Key Derivation Invariant defines an industrial-grade behavioral standard for security engineering. Enforces strict cryptographic domain separation and client-side isolation when deriving symmetric keys via the WebAuthn PRF (pseudo-random function) extension. Guarantees that raw PRF outputs and derived symmetric encryption keys are non-extractable, zeroized immediately after initialization, and never exfiltrated to application backends, session storage, or telemetry streams. 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: Exposing Raw PRF Outputs to Backends or Storing Extractable Derived Symmetric Keys 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 DriftExposing Raw PRF Outputs to Backends or Storing Extractable Derived Symmetric KeysCritical
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 strip the `prf` extension output from the WebAuthn `AuthenticationCredential` before sending the assertion response to the backend server.

Engineers MUST ALWAYS strip the `prf` extension output from the WebAuthn `AuthenticationCredential` before sending the assertion response to the backend server.

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 ingest the 32-byte raw PRF output directly into `crypto.subtle.importKey` as an ephemeral HKDF master key with `extractable

Engineers MUST ALWAYS ingest the 32-byte raw PRF output directly into `crypto.subtle.importKey` as an ephemeral HKDF master key with `extractable: false`.

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 HKDF (`HMAC-SHA-256`) with distinct, application-specific `info` and `salt` parameters to derive symmetric encryption keys (e.g., `AES-GCM-256`), ensuring strict domain separation.

Engineers MUST ALWAYS use HKDF (`HMAC-SHA-256`) with distinct, application-specific `info` and `salt` parameters to derive symmetric encryption keys (e.g., `AES-GCM-256`), ensuring strict domain separation.

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 persist raw PRF results, intermediate keying material, or derived keys into `localStorage`, `sessionStorage`, `IndexedDB`, or cookies.

Engineers MUST NOT persist raw PRF results, intermediate keying material, or derived keys into `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.
5

Components NEVER expose derived `CryptoKey` handles to client telemetry, error trackers, or unprivileged UI state trees.

Components NEVER expose derived `CryptoKey` handles to client telemetry, error trackers, or unprivileged UI state trees.

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 SHOULD zeroize ephemeral `Uint8Array` memory buffers containing PRF inputs or outputs immediately after `crypto.subtle` key derivation.

Code SHOULD zeroize ephemeral `Uint8Array` memory buffers containing PRF inputs or outputs immediately after `crypto.subtle` 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.
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 Key Derivation Invariant critical for AI coding assistants?

Enforces strict cryptographic domain separation and client-side isolation when deriving symmetric keys via the WebAuthn PRF (pseudo-random function) extension. Guarantees that raw PRF outputs and derived symmetric encryption keys are non-extractable, zeroized immediately after initialization, and never exfiltrated to application backends, session storage, or telemetry streams. 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 (Exposing Raw PRF Outputs to Backends or Storing Extractable Derived Symmetric Keys) 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