npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

cloaklog-node

v0.1.1

Published

Zero-knowledge observability encryption layer for LLM logs

Readme

CloakLog - Zero-Knowledge Observability for LLMs

npm version License: MIT TypeScript

CloakLog encrypts sensitive LLM text before it leaves your app, while preserving observability metadata in clear text.

[!WARNING] Status: MVP / Not production-ready by default. [email protected] is an early security-focused MVP. It is suitable for evaluation and pilot usage, but not yet a complete enterprise security platform.

[!NOTE] For vulnerability reporting, see SECURITY.md.

The Problem

If you forward raw OpenAI requests/responses to observability platforms (Datadog, Langfuse, etc.), you may expose:

  • PII (names, emails, bank data)
  • customer secrets and internal business data
  • regulated content to third-party infrastructure

Even when logs are useful, plaintext prompts are a major security and compliance risk.

The Solution

CloakLog applies two security controls at runtime:

  1. Selective Redaction
    Only sensitive text fields (content) are encrypted. Metadata stays clear for dashboards and analytics (model, usage.total_tokens, latency).

  2. Envelope Encryption

    • Local ephemeral key: AES-256-GCM encrypts text payloads
    • Key wrapping: AES key is encrypted with your RSA public key (RSA-OAEP-SHA256)

Result: logs are still operationally useful, but sensitive text is unreadable without your private key.

Installation

npm install cloaklog-node openai

openai is a peer dependency for the OpenAI adapter.

Quick Start

import {
  decryptContentWithKey,
  decryptDataKey,
  generateKeyPair,
  wrapOpenAI,
  type EncryptedField,
  type EncryptedLogPayload,
} from 'cloaklog-node';

type MockCreateParams = {
  model: string;
  messages: Array<{ role: string; content: string }>;
};

type MockCreateResponse = {
  id: string;
  model: string;
  choices: Array<{ message: { role: 'assistant'; content: string } }>;
  usage: { prompt_tokens: number; completion_tokens: number; total_tokens: number };
};

function asEncryptedField(value: unknown): EncryptedField {
  if (typeof value !== 'object' || value === null || !("_cloaklog" in value) || !("payload" in value)) {
    throw new Error('Invalid encrypted field');
  }
  return value as EncryptedField;
}

async function demo() {
  const { publicKey, privateKey } = await generateKeyPair();

  const openaiMock = {
    chat: {
      completions: {
        create: async (...args: any[]): Promise<MockCreateResponse> => ({
          id: 'chatcmpl_demo_001',
          model: (args[0] as MockCreateParams).model,
          choices: [
            {
              message: {
                role: 'assistant',
                content: 'Processed. Customer file validated for account 123456789.',
              },
            },
          ],
          usage: { prompt_tokens: 31, completion_tokens: 17, total_tokens: 48 },
        }),
      },
    },
  };

  let capturedLog: EncryptedLogPayload | null = null;

  const wrapped = wrapOpenAI(openaiMock, publicKey, {
    onLog: (log) => {
      capturedLog = log;
      console.log('Encrypted observability payload:', JSON.stringify(log, null, 2));
    },
  });

  await wrapped.chat.completions.create({
    model: 'gpt-5.4-mini',
    messages: [{ role: 'user', content: 'Le compte bancaire de M. Dupont est le 123456789' }],
  });

  if (!capturedLog) throw new Error('No encrypted log captured');

  const dataKey = decryptDataKey(capturedLog.encryptedKey, privateKey);
  const reqContent = asEncryptedField((capturedLog.request.messages as Array<{ content: unknown }>)[0]?.content);
  const resContent = asEncryptedField(
    (capturedLog.response.choices as Array<{ message: { content: unknown } }>)[0]?.message.content,
  );

  console.log('Decrypted request:', decryptContentWithKey(reqContent.payload, dataKey));
  console.log('Decrypted response:', decryptContentWithKey(resContent.payload, dataKey));
}

demo().catch(console.error);

Visual Proof

Run:

npm run demo

Example output (trimmed):

CLOAKLOG DEMO — ENTERPRISE: ENCRYPTED LLM LOG BEFORE OBSERVABILITY
✓ RSA key pair generated

APPEL LLM (MOCK) AVEC DONNÉE ULTRA-SENSIBLE
Entrée sensible: Le compte bancaire de M. Dupont est le 123456789

LOG CHIFFRÉ ENVOYÉ PAR L’ENTREPRISE
{
  "scheme": "cloaklog-envelope-v1",
  "keyAlgorithm": "rsa-oaep-sha256",
  "metadata": {
    "keyId": "tenant-eu-1",
    "model": "gpt-5.4-mini",
    "usage": {
      "prompt_tokens": 31,
      "completion_tokens": 17,
      "total_tokens": 48
    },
    "latencyMs": 2
  },
  "request": {
    "messages": [
      {
        "role": "user",
        "content": {
          "_cloaklog": "encrypted",
          "payload": {
            "alg": "aes-256-gcm",
            "iv": "...",
            "ciphertext": "...",
            "authTag": "..."
          }
        }
      }
    ]
  }
}

Vérification fuite plaintext: OK
Métadonnées en clair:
- usage.total_tokens: 48

DÉCHIFFREMENT CÔTÉ ENTREPRISE
✓ Requête déchiffrée: Le compte bancaire de M. Dupont est le 123456789

Architecture / How It Works

  • Core + Adapter design
    • src/core/crypto.ts: pure crypto utilities (no SDK coupling)
    • src/adapters/openai.ts: OpenAI interception wrapper (wrapOpenAI)
  • Zero external crypto dependencies
    • Uses only Node.js native crypto
  • Fail-secure behavior
    • On encryption failure, no plaintext log fallback is emitted

Why CTOs Choose CloakLog

  • Risk reduction without observability loss: sensitive text is encrypted, while model, tokens, and latency remain usable.
  • Fast adoption: drop-in wrapper around existing OpenAI calls, with no infrastructure migration.
  • Security by default: Node native crypto only (AES-256-GCM + RSA-OAEP-SHA256), fail-secure logging behavior.
  • Future-proof architecture: strict Core/Adapter separation to extend to more LLM providers over time.

Security Notes

  • Encrypts only content fields in this MVP
  • function_call and tool_calls are intentionally out of scope for this first release
  • Keep your RSA private key in a secure key management system (KMS/HSM/Vault)

Production Scope (Current)

What this MVP provides now:

  • Local envelope encryption (AES-256-GCM + RSA-OAEP-SHA256) for messages.content and response message.content
  • Fail-secure behavior: no plaintext observability payload when encryption pipeline fails
  • Metadata preservation for operations (model, token usage, latency)
  • Optional metadata.keyId field to prepare key rotation workflows

What is out of scope right now:

  • Built-in KMS integrations (AWS KMS/GCP KMS/Vault)
  • Coverage for tool_calls, function_call, and non-OpenAI providers
  • Policy engine, signatures/non-repudiation, and formal compliance controls

Roadmap Snapshot

  • P0: docs hardening, security policy, schema/versioning discipline, fail-secure test coverage
  • P1: KMS integration + key rotation lifecycle + perf/reliability metrics
  • P2: multi-provider adapters + policy engine + stronger transport and integrity controls
  • P3: enterprise trust posture (third-party assessment, compliance evidence, release provenance)