While OmniBrief is engineered to run 100% locally using Chrome's Gemini Nano model, power users often configure external cloud models (like OpenAI GPT-4o, Anthropic Claude 3.5 Sonnet, or Gemini 1.5 Pro) to handle deeper analysis. Hooking into these cloud engines requires storing API credentials inside the extension wrapper.

However, browser extension storage is notoriously vulnerable. A naive implementation that writes API keys as plaintext to chrome.storage.local leaves credentials exposed. If a malicious script exploits a XSS vulnerability or if the device itself is compromised, the plaintext API keys can be scraped instantly, leading to significant cloud billing surprises.

To eliminate this threat vector, ZumiLabs engineers implemented a client-side Cryptographic Lockbox inside OmniBrief using the browser's native Web Crypto API.

Key Technical Concepts Covered

  • The Plaintext Risk: Why unencrypted chrome storage is a major vulnerability.
  • PBKDF2 Key Derivation: Generating high-entropy encryption keys from short user PINs.
  • AES-GCM 256-bit Encryption: Authenticated encryption that detects tampering with stored ciphertext.
  • Short-lived In-Memory Keys: Resting decrypted key buffers strictly in session state variables.

Part of the engineering behind OmniBrief.

Tested with Chrome 149 (July 2026).

Deriving Keys via PBKDF2

Encryption requires an encryption key. If you hardcode a key inside the extension source code, any developer can inspect the package and retrieve it. The key must be generated dynamically from user input-specifically, a short, memorable user-defined security PIN.

To convert a low-entropy PIN (like a 6-digit code) into a high-entropy 256-bit cryptographic key, OmniBrief uses PBKDF2 (Password-Based Key Derivation Function 2) with a random Salt and 310,000 hashing iterations using SHA-256:

// PBKDF2 Derivation inside background lockbox script
async function deriveEncryptionKey(pinString, saltBuffer) {
  const enc = new TextEncoder();
  
  // Import raw PIN text as a base key
  const baseKey = await window.crypto.subtle.importKey(
    "raw",
    enc.encode(pinString),
    "PBKDF2",
    false,
    ["deriveKey"]
  );

  // Derive the actual 256-bit AES key
  return window.crypto.subtle.deriveKey(
    {
      name: "PBKDF2",
      salt: saltBuffer,
      iterations: 310000,
      hash: "SHA-256"
    },
    baseKey,
    { name: "AES-GCM", length: 256 },
    false, // Key is non-exportable from memory
    ["encrypt", "decrypt"]
  );
}

Encrypting with AES-GCM

Once derived, credentials are encrypted using AES-GCM (Galois/Counter Mode), which provides both confidentiality and integrity authentication. This means if an attacker attempts to modify the encrypted text in storage, decryption will fail immediately rather than outputting garbage data.

OmniBrief generates a unique Initialization Vector (IV) for each encryption pass, ensuring that identical API keys result in completely different ciphertexts:

async function encryptAPIKey(apiKey, pin) {
  const enc = new TextEncoder();
  const salt = window.crypto.getRandomValues(new Uint8Array(16));
  const iv = window.crypto.getRandomValues(new Uint8Array(12)); // 96-bit IV
  
  const key = await deriveEncryptionKey(pin, salt);
  
  const ciphertext = await window.crypto.subtle.encrypt(
    { name: "AES-GCM", iv: iv },
    key,
    enc.encode(apiKey)
  );

  // Store salt, iv, and ciphertext as base64 strings in chrome.storage.local
  return {
    salt: btoa(String.fromCharCode(...salt)),
    iv: btoa(String.fromCharCode(...iv)),
    ciphertext: btoa(String.fromCharCode(...new Uint8Array(ciphertext)))
  };
}

Session Memory Isolation

To balance security and user experience, OmniBrief avoids prompting the user for their PIN on every single API request. Instead, we use chrome.storage.session (introduced in Manifest V3).

When the browser session boots, the user inputs their PIN once in the Sidepanel. OmniBrief decrypts the key and writes it to chrome.storage.session. Unlike local storage, session variables are stored exclusively in system RAM and are cleared the moment the browser window is closed. Decrypted keys never touch the physical hard drive.

Conclusion: Complete Cryptographic Autonomy

By pairing PBKDF2 key derivation with AES-GCM authenticated encryption, OmniBrief protects stored cloud API keys against casual inspection and offline extraction. It is worth being precise about the boundary: this secures keys at rest. A short PIN is inherently low-entropy, and once a key is decrypted into memory it is exposed to any code running inside the extension session - encryption at rest is not a defense against a compromised browser or malicious extension code.