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

WebAuthn Level 3 PRF Extension Hardware-Bound Symmetric Key Derivation Contract

Enforces strict end-to-end zero-knowledge client-side symmetric key derivation using the WebAuthn Level 3 Pseudo-Random Function (PRF) extension (HMAC-secret). Mandates that PRF seed outputs never traverse the network, persistent storage, or telemetry streams, and requires continuous salt isolation, ephemeral memory hygiene, and constant-time key derivation via HKDF.

Prohibited Anti-Pattern: Transmitting PRF Outputs or Deriving Persistent Root Keys in Plaintext Client/Server Memory

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: WebAuthn Level 3 PRF Extension Hardware-Bound Symmetric Key Derivation Contract - Enforces strict end-to-end zero-knowledge client-side symmetric key derivation using the WebAuthn Level 3 Pseudo-Random Function (PRF) extension (HMAC-secret). Mandates that PRF seed outputs never traverse the network, persistent storage, or telemetry streams, and requires continuous salt isolation, ephemeral memory hygiene, and constant-time key derivation via HKDF.
globs: src/**/*.{ts,tsx,js,mjs}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/webauthn-prf-hardware-bound-key-derivation-contract"
---

# WebAuthn Level 3 PRF Extension Hardware-Bound Symmetric Key Derivation Contract

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Transmitting PRF Outputs or Deriving Persistent Root Keys in Plaintext Client/Server Memory

## System Constraints
You are a Principal Security Architect enforcing zero-knowledge hardware-bound cryptography via the WebAuthn Level 3 PRF extension. You must guarantee that raw PRF outputs (first/second symmetric seeds) remain ephemeral, hardware-isolated, and are immediately imported into non-extractable WebCrypto CryptoKey handles through RFC 5869 HKDF. Under no circumstances should raw PRF outputs, evaluation salts, or derived encryption keys be transmitted to relying parties, exposed to third-party scripts, or serialized into persistent storage (e.g., localStorage, IndexedDB).

## Strict Guidelines
- Engineers MUST ALWAYS verify navigator.credentials and PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() before requesting PRF extensions.
- Engineers MUST ALWAYS declare extensions: { prf: { eval: { first: Uint8Array } } } in credential get assertions, using domain-separated, cryptographically random 32-byte salts.
- Engineers MUST ALWAYS immediately import the PRF output buffer into a WebCrypto non-extractable CryptoKey using HKDF (RFC 5869) and zeroize the intermediary ArrayBuffer.
- Engineers MUST NEVER transmit the PRF output or intermediate derived keys over the network, serialize them to disk, or log them in telemetry.
- Engineers MUST NOT allow derived CryptoKey objects to have extractable set to true when generating wrapping or bulk encryption keys.
- Code SHOULD enforce userVerification: 'required' in credential options to ensure hardware enclave biometric or PIN authentication bounds the PRF evaluation.
- Services MUST validate that the relying party server only supplies assertion challenges and salts, never processing or accepting raw PRF outputs.

## Bad vs Good Implementations
### Hardware PRF Key Derivation and WebCrypto Non-Extractable Import

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: The code fails to enforce userVerification: 'required', leaving the hardware key derivation unauthenticated. Furthermore, it leaks the raw PRF symmetric output over the network to the server, completely breaking the zero-knowledge hardware-bound invariant.
```typescript
async function deriveVaultKey(credentialId: Uint8Array, salt: Uint8Array): Promise<void> {
  // Anti-pattern: Missing userVerification, extractable key, and transmitting raw secret to backend
  const assertion = (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 extensionResults = assertion.getClientExtensionResults();
  const rawSecret = extensionResults.prf?.results?.first;

  if (!rawSecret) throw new Error('PRF failed');

  // CRITICAL SECURITY FLAW: Sending PRF raw secret to backend server for derivation
  await fetch('/api/vault/unlock', {
    method: 'POST',
    body: JSON.stringify({ rawSecret: Array.from(new Uint8Array(rawSecret)) })
  });
}
```

#### Production Standard (Correct)
> **Standard**: The good pattern enforces userVerification: 'required', validates PRF presence, imports raw bytes directly into an unextractable HKDF WebCrypto key, performs domain-separated AES-GCM-256 key derivation with extractable: false, and safely wipes the temporary ArrayBuffer.
```typescript
async function deriveVaultKey(
  credentialId: Uint8Array,
  salt: Uint8Array,
  infoContext: Uint8Array
): Promise<CryptoKey> {
  // Invariant: Enforce hardware assertion with userVerification and PRF extension
  const assertion = (await navigator.credentials.get({
    publicKey: {
      challenge: crypto.getRandomValues(new Uint8Array(32)),
      allowCredentials: [{ id: credentialId, type: 'public-key' }],
      userVerification: 'required',
      extensions: {
        prf: {
          eval: { first: salt }
        }
      }
    }
  })) as PublicKeyCredential | null;

  if (!assertion) {
    throw new Error('Credential assertion failed or was cancelled');
  }

  const extensionResults = assertion.getClientExtensionResults();
  const rawPrfOutput = extensionResults.prf?.results?.first;

  if (!rawPrfOutput || !(rawPrfOutput instanceof ArrayBuffer)) {
    throw new Error('Authenticator did not return a valid PRF output buffer');
  }

  try {
    // Invariant: Import ephemeral PRF output as raw HKDF input key material (IKM)
    const baseKey = await crypto.subtle.importKey(
      'raw',
      rawPrfOutput,
      'HKDF',
      false,
      ['deriveKey']
    );

    // Invariant: Derive non-extractable AES-GCM-256 key with domain separation
    const vaultKey = await crypto.subtle.deriveKey(
      {
        name: 'HKDF',
        hash: 'SHA-256',
        salt: salt,
        info: infoContext
      },
      baseKey,
      { name: 'AES-GCM', length: 256 },
      false, // non-extractable
      ['encrypt', 'decrypt']
    );

    return vaultKey;
  } finally {
    // Invariant: Zeroize buffer memory immediately after import
    new Uint8Array(rawPrfOutput).fill(0);
  }
}
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: WebAuthn Level 3 PRF Extension Hardware-Bound Symmetric Key Derivation Contract

WebAuthn Level 3 PRF Extension Hardware-Bound Symmetric Key Derivation Contract defines an industrial-grade behavioral standard for security engineering. Enforces strict end-to-end zero-knowledge client-side symmetric key derivation using the WebAuthn Level 3 Pseudo-Random Function (PRF) extension (HMAC-secret). Mandates that PRF seed outputs never traverse the network, persistent storage, or telemetry streams, and requires continuous salt isolation, ephemeral memory hygiene, and constant-time key derivation via HKDF. 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: Transmitting PRF Outputs or Deriving Persistent Root Keys in Plaintext Client/Server Memory 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 DriftTransmitting PRF Outputs or Deriving Persistent Root Keys in Plaintext Client/Server MemoryCritical
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 navigator.credentials and PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() before requesting PRF extensions.

Engineers MUST ALWAYS verify navigator.credentials and PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() before requesting PRF extensions.

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 declare extensions

Engineers MUST ALWAYS declare extensions: { prf: { eval: { first: Uint8Array } } } in credential get assertions, using domain-separated, cryptographically random 32-byte salts.

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 immediately import the PRF output buffer into a WebCrypto non-extractable CryptoKey using HKDF (RFC 5869) and zeroize the intermediary ArrayBuffer.

Engineers MUST ALWAYS immediately import the PRF output buffer into a WebCrypto non-extractable CryptoKey using HKDF (RFC 5869) and zeroize the intermediary ArrayBuffer.

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 NEVER transmit the PRF output or intermediate derived keys over the network, serialize them to disk, or log them in telemetry.

Engineers MUST NEVER transmit the PRF output or intermediate derived keys over the network, serialize them to disk, or log them in telemetry.

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

Engineers MUST NOT allow derived CryptoKey objects to have extractable set to true when generating wrapping or bulk encryption keys.

Engineers MUST NOT allow derived CryptoKey objects to have extractable set to true when generating wrapping or bulk encryption keys.

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 enforce userVerification

Code SHOULD enforce userVerification: 'required' in credential options to ensure hardware enclave biometric or PIN authentication bounds the PRF evaluation.

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

Services MUST validate that the relying party server only supplies assertion challenges and salts, never processing or accepting raw PRF outputs.

Services MUST validate that the relying party server only supplies assertion challenges and salts, never processing or accepting raw PRF outputs.

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 Extension Hardware-Bound Symmetric Key Derivation Contract critical for AI coding assistants?

Enforces strict end-to-end zero-knowledge client-side symmetric key derivation using the WebAuthn Level 3 Pseudo-Random Function (PRF) extension (HMAC-secret). Mandates that PRF seed outputs never traverse the network, persistent storage, or telemetry streams, and requires continuous salt isolation, ephemeral memory hygiene, and constant-time key derivation via HKDF. 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 (Transmitting PRF Outputs or Deriving Persistent Root Keys in Plaintext Client/Server Memory) 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