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

WebAuthn PRF Hardware-Bound Envelope Encryption Standard

Mandates zero-trust client-side envelope encryption rooted in hardware authenticators using the WebAuthn PRF (Pseudo-Random Function) extension. Prohibits transmission or persistence of raw PRF bytes, unencrypted Data Encryption Keys (DEKs), or plaintext payloads to remote APIs. Requires strict HKDF derivation of Key Encryption Keys (KEKs) and cryptographically fresh per-record AES-256-GCM nonce and key generation.

Prohibited Anti-Pattern: Leaking Raw Hardware PRF Outputs, Using PRF as Direct Symmetric Keys, or Transmitting Unwrapped DEKs

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: WebAuthn PRF Hardware-Bound Envelope Encryption Standard - Mandates zero-trust client-side envelope encryption rooted in hardware authenticators using the WebAuthn PRF (Pseudo-Random Function) extension. Prohibits transmission or persistence of raw PRF bytes, unencrypted Data Encryption Keys (DEKs), or plaintext payloads to remote APIs. Requires strict HKDF derivation of Key Encryption Keys (KEKs) and cryptographically fresh per-record AES-256-GCM nonce and key generation.
globs: src/**/*.{ts,tsx}, lib/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/webauthn-prf-envelope-encryption-guardrail"
---

# WebAuthn PRF Hardware-Bound Envelope Encryption Standard

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Leaking Raw Hardware PRF Outputs, Using PRF as Direct Symmetric Keys, or Transmitting Unwrapped DEKs

## System Constraints
You are a Principal Security Architect enforcing the WebAuthn PRF Extension Client-Side Envelope Encryption Standard. Mandate that all client-side sensitive data encryption is hardware-bound via WebAuthn PRF. Ensure raw PRF output is never serialized, logged, transmitted, or reused directly as a cipher key. Enforce standard envelope encryption: Hardware PRF -> HKDF Extract-and-Expand -> Key Encryption Key (KEK) -> Wrapped Data Encryption Key (DEK). Fail closed immediately if the authenticator does not support or returns empty PRF evaluations.

## Strict Guidelines
- Engineers MUST ALWAYS derive the Key Encryption Key (KEK) from raw WebAuthn PRF output using HKDF (HMAC-based Extract-and-Expand Key Derivation Function, RFC 5869) with SHA-256 and an explicit, domain-separated info context string.
- Engineers MUST NEVER use the raw PRF evaluation bytes directly as an AES-GCM or ChaCha20 cipher key.
- Engineers MUST generate a unique, cryptographically random ephemeral Data Encryption Key (DEK) and a fresh 96-bit IV via crypto.getRandomValues for every single encryption operation.
- Components NEVER transmit plaintext payloads, unwrapped DEKs, or raw PRF evaluation bytes to backend endpoints or unmanaged storage (localStorage, sessionStorage, IndexedDB).
- Services MUST fail closed and reject encryption operations if the WebAuthn assertion response lacks extensions.prf.results.first or if authenticatorData indicates PRF extension failure.
- Code SHOULD zeroize or clear raw PRF Uint8Array buffers immediately after deriving the non-extractable KEK in WebCrypto.

## Bad vs Good Implementations
### Hardware PRF Derivation and Client-Side Envelope Encryption

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: The anti-pattern fails to check PRF extension support, transmits the raw hardware PRF secret directly across the network, uses a static all-zero IV causing catastrophic nonce reuse in AES-GCM, and skips HKDF derivation.
```typescript
import axios from 'axios';

// ANTI-PATTERN: Direct PRF use, insecure key derivation, and leaking DEK/plaintext to server
export async function encryptAndSave(credentialId: string, plaintext: string) {
  const assertion = await navigator.credentials.get({
    publicKey: {
      challenge: new Uint8Array([1, 2, 3, 4]),
      allowCredentials: [{ id: Buffer.from(credentialId, 'base64'), type: 'public-key' }],
      extensions: {
        // @ts-ignore
        prf: { eval: { first: new Uint8Array(32) } }
      }
    }
  }) as PublicKeyCredential;

  // INSECURE: Extracting PRF raw output without checking validity
  const results = (assertion.getClientExtensionResults() as any).prf;
  const rawPrf = new Uint8Array(results.results.first);

  // CRITICAL VULNERABILITY: Transmitting raw PRF secret or using it directly without HKDF
  await axios.post('/api/keys/sync', { prfSecret: Array.from(rawPrf) });

  // INSECURE: Fixed IV and using PRF directly as AES key
  const key = await crypto.subtle.importKey('raw', rawPrf, { name: 'AES-GCM' }, false, ['encrypt']);
  const iv = new Uint8Array(12); // Reused static IV
  const ciphertext = await crypto.subtle.encrypt(
    { name: 'AES-GCM', iv },
    key,
    new TextEncoder().encode(plaintext)
  );

  return { ciphertext: Buffer.from(ciphertext).toString('base64') };
}
```

#### Production Standard (Correct)
> **Standard**: Implements defense-in-depth zero-trust envelope encryption. Hardware PRF is rigorously derived via HKDF-SHA-256 with non-extractable keys; raw PRF memory is explicitly zeroized in a finally block; each payload receives an ephemeral DEK with isolated random IVs; and only ciphertext and wrapped DEK are emitted.
```typescript
export interface EncryptedEnvelope {
  encryptedDek: string;
  ciphertext: string;
  iv: string;
  dekWrapIv: string;
}

const HKDF_INFO_KEK = new TextEncoder().encode('authn:prf:v1:envelope:kek');
const HKDF_SALT = new TextEncoder().encode('authn:prf:domain:salt:v1');

export async function encryptWithPrfEnvelope(
  credentialId: Uint8Array,
  challenge: Uint8Array,
  prfSalt: Uint8Array,
  plaintext: Uint8Array
): Promise<EncryptedEnvelope> {
  const assertion = await navigator.credentials.get({
    publicKey: {
      challenge,
      allowCredentials: [{ id: credentialId, type: 'public-key' }],
      extensions: {
        prf: { eval: { first: prfSalt } }
      }
    }
  }) as PublicKeyCredential | null;

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

  const extResults = assertion.getClientExtensionResults() as AuthenticationExtensionsClientOutputs & {
    prf?: { results?: { first?: ArrayBuffer } };
  };

  const rawPrfBuffer = extResults.prf?.results?.first;
  if (!rawPrfBuffer || rawPrfBuffer.byteLength !== 32) {
    throw new Error('Authenticator did not return a valid 32-byte PRF extension output');
  }

  const rawPrfBytes = new Uint8Array(rawPrfBuffer);

  try {
    // 1. Derive Non-Extractable KEK via HKDF-SHA256 from Hardware PRF Seed
    const prfKeyMaterial = await crypto.subtle.importKey(
      'raw',
      rawPrfBytes,
      'HKDF',
      false,
      ['deriveKey']
    );

    const kek = await crypto.subtle.deriveKey(
      {
        name: 'HKDF',
        hash: 'SHA-256',
        salt: HKDF_SALT,
        info: HKDF_INFO_KEK
      },
      prfKeyMaterial,
      { name: 'AES-GCM', length: 256 },
      false,
      ['wrapKey']
    );

    // 2. Generate Ephemeral AES-256-GCM DEK for Payload Encryption
    const dek = await crypto.subtle.generateKey(
      { name: 'AES-GCM', length: 256 },
      true,
      ['encrypt']
    );

    // 3. Encrypt Plaintext Payload with DEK using Fresh 96-bit Nonce
    const dataIv = crypto.getRandomValues(new Uint8Array(12));
    const ciphertextBuffer = await crypto.subtle.encrypt(
      { name: 'AES-GCM', iv: dataIv },
      dek,
      plaintext
    );

    // 4. Wrap DEK with Hardware-Derived KEK using Fresh Nonce
    const wrapIv = crypto.getRandomValues(new Uint8Array(12));
    const wrappedDekBuffer = await crypto.subtle.wrapKey(
      'raw',
      dek,
      kek,
      { name: 'AES-GCM', iv: wrapIv }
    );

    return {
      ciphertext: btoa(String.fromCharCode(...new Uint8Array(ciphertextBuffer))),
      encryptedDek: btoa(String.fromCharCode(...new Uint8Array(wrappedDekBuffer))),
      iv: btoa(String.fromCharCode(...dataIv)),
      dekWrapIv: btoa(String.fromCharCode(...wrapIv))
    };
  } finally {
    // Zeroize sensitive ephemeral PRF memory buffer
    rawPrfBytes.fill(0);
  }
}
```

Recommended MCP Servers (mcp-serverlist.com)

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

Architectural Specification & Invariant Rationale

Architectural Invariant Design: WebAuthn PRF Hardware-Bound Envelope Encryption Standard

WebAuthn PRF Hardware-Bound Envelope Encryption Standard defines an industrial-grade behavioral standard for security engineering. Mandates zero-trust client-side envelope encryption rooted in hardware authenticators using the WebAuthn PRF (Pseudo-Random Function) extension. Prohibits transmission or persistence of raw PRF bytes, unencrypted Data Encryption Keys (DEKs), or plaintext payloads to remote APIs. Requires strict HKDF derivation of Key Encryption Keys (KEKs) and cryptographically fresh per-record AES-256-GCM nonce and key generation. 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 Hardware PRF Outputs, Using PRF as Direct Symmetric Keys, or Transmitting Unwrapped DEKs 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 Hardware PRF Outputs, Using PRF as Direct Symmetric Keys, or Transmitting Unwrapped DEKsCritical
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 derive the Key Encryption Key (KEK) from raw WebAuthn PRF output using HKDF (HMAC-based Extract-and-Expand Key Derivation Function, RFC 5869) with SHA-256 and an explicit, domain-separated info context string.

Engineers MUST ALWAYS derive the Key Encryption Key (KEK) from raw WebAuthn PRF output using HKDF (HMAC-based Extract-and-Expand Key Derivation Function, RFC 5869) with SHA-256 and an explicit, domain-separated info context string.

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 use the raw PRF evaluation bytes directly as an AES-GCM or ChaCha20 cipher key.

Engineers MUST NEVER use the raw PRF evaluation bytes directly as an AES-GCM or ChaCha20 cipher key.

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 generate a unique, cryptographically random ephemeral Data Encryption Key (DEK) and a fresh 96-bit IV via crypto.getRandomValues for every single encryption operation.

Engineers MUST generate a unique, cryptographically random ephemeral Data Encryption Key (DEK) and a fresh 96-bit IV via crypto.getRandomValues for every single encryption operation.

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

Components NEVER transmit plaintext payloads, unwrapped DEKs, or raw PRF evaluation bytes to backend endpoints or unmanaged storage (localStorage, sessionStorage, IndexedDB).

Components NEVER transmit plaintext payloads, unwrapped DEKs, or raw PRF evaluation bytes to backend endpoints or unmanaged storage (localStorage, sessionStorage, IndexedDB).

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 fail closed and reject encryption operations if the WebAuthn assertion response lacks extensions.prf.results.first or if authenticatorData indicates PRF extension failure.

Services MUST fail closed and reject encryption operations if the WebAuthn assertion response lacks extensions.prf.results.first or if authenticatorData indicates PRF extension failure.

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 or clear raw PRF Uint8Array buffers immediately after deriving the non-extractable KEK in WebCrypto.

Code SHOULD zeroize or clear raw PRF Uint8Array buffers immediately after deriving the non-extractable KEK in WebCrypto.

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 Hardware-Bound Envelope Encryption Standard critical for AI coding assistants?

Mandates zero-trust client-side envelope encryption rooted in hardware authenticators using the WebAuthn PRF (Pseudo-Random Function) extension. Prohibits transmission or persistence of raw PRF bytes, unencrypted Data Encryption Keys (DEKs), or plaintext payloads to remote APIs. Requires strict HKDF derivation of Key Encryption Keys (KEKs) and cryptographically fresh per-record AES-256-GCM nonce and key generation. 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 Hardware PRF Outputs, Using PRF as Direct Symmetric Keys, or Transmitting Unwrapped DEKs) 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