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

privaro-sdk

v0.1.0

Published

Privacy Infrastructure for Enterprise AI — iCommunity Labs

Readme

privaro-sdk

Privacy infrastructure for enterprise AI — intercepts PII before it reaches any LLM.

Drop-in SDK for Node.js and edge runtimes. Wraps your existing OpenAI, Anthropic, LangChain, or Vercel AI calls with automatic PII detection, tokenisation, and blockchain-certified audit logging — no architecture changes required.

npm install privaro-sdk

Quickstart

import { PrivaroClient } from "privaro-sdk";

const privaro = new PrivaroClient({
  apiKey: process.env.PRIVARO_API_KEY!,      // starts with "prvr_"
  pipelineId: process.env.PRIVARO_PIPELINE_ID!,
});

const result = await privaro.protect(
  "Solicitante: Laura Sánchez Blanco, DNI 23456789D, IBAN ES98 2100 0418 6819 6340 7321"
);

console.log(result.protected);
// → "Solicitante: [NM-0001], DNI [ID-0001], IBAN [BK-0001]"

console.log(result.total_detected);  // 3
console.log(result.gdpr_compliant);  // true
console.log(result.audit_log_id);    // Supabase row UUID — linked to iBS blockchain cert

Pass result.protected to your LLM. The original values are stored in the Privaro token vault — retrievable on demand, never logged in plaintext.


Installation

npm install privaro-sdk

Node.js ≥ 18 required. No native dependencies — uses the built-in fetch API.

Peer dependencies are optional — install only what you use:

npm install openai          # OpenAI adapter
npm install @langchain/openai langchain   # LangChain adapter
npm install ai              # Vercel AI SDK adapter

Configuration

const privaro = new PrivaroClient({
  apiKey: "prvr_...",           // required — from /app/admin/api-keys
  pipelineId: "uuid",          // required — from /app/pipelines
  baseUrl: "https://...",      // optional — defaults to production Railway endpoint
  timeout: 10_000,             // optional — ms, default 10s
  defaultMode: "tokenise",     // optional — tokenise | anonymise | block
});

Get your API key and pipeline ID from privaro.ai/app/admin.


Core API

client.protect(prompt, opts?)

Detect and tokenise PII. Writes an audit log entry with iBS blockchain certification.

const result = await privaro.protect("Patient María García, DNI 34521789X", {
  mode: "tokenise",          // tokenise | anonymise | block
  reversible: true,          // store reversible tokens in vault
  includeDetections: true,   // include per-entity details
});

// Send result.protected to your LLM
const llmResponse = await openai.chat.completions.create({
  messages: [{ role: "user", content: result.protected }],
  model: "gpt-4o",
});

ProtectResult properties:

result.protected        // tokenised prompt — send to LLM
result.original         // original text — stored client-side only
result.detections       // per-entity details array
result.total_detected   // number of PII entities found
result.total_masked     // number tokenised/anonymised
result.gdpr_compliant   // boolean
result.risk_score       // 0.0–1.0 | null
result.riskLevel        // "high" | "medium" | "low" | "unknown"
result.hasPii           // boolean convenience
result.isSafe           // gdpr_compliant && leaked === 0
result.audit_log_id     // Supabase UUID for DPO reports
result.processing_ms    // detection latency
result.summary()        // one-line log string

client.detect(prompt)

Scan for PII without masking. No audit log written, no state changes. Use for analysis and reporting.

const result = await privaro.detect("Please call María at 677-23-45-67");
result.detections.forEach(d => {
  console.log(d.type, d.severity, d.start, d.end);
  // "phone", "high", 21, 33
});

client.relay(messages, opts?)

Full-cycle relay: protect → route to your configured LLM → de-tokenise response. Requires an LLM provider configured in /app/admin/providers.

const result = await privaro.relay([
  { role: "user", content: "Analiza el contrato de María García, DNI 34521789X..." }
]);

console.log(result.response);   // LLM reply with original values restored
console.log(result.pii_masked); // number of entities protected

Adapters

OpenAI — drop-in wrapper

Replace your OpenAI client with the Privaro-wrapped version. Identical API surface.

import OpenAI from "openai";
import { PrivaroClient } from "privaro-sdk";
import { wrapOpenAI } from "privaro-sdk/adapters/openai";

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const privaro = new PrivaroClient({
  apiKey: process.env.PRIVARO_API_KEY!,
  pipelineId: process.env.PRIVARO_PIPELINE_ID!,
});

const safe = wrapOpenAI(openai, privaro);

// Exactly the same call — PII protected and de-tokenised automatically
const response = await safe.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Analiza hipoteca de Laura Sánchez, DNI 23456789D" }],
});

console.log(response.choices[0].message.content); // real names restored in response
console.log(response._privaro?.pii_detected);      // 2

LangChain — callback handler

Attach to any LangChain LLM or chain.

import { ChatOpenAI } from "@langchain/openai";
import { PrivaroClient } from "privaro-sdk";
import { PrivaroCallbackHandler } from "privaro-sdk/adapters/langchain";

const privaro = new PrivaroClient({
  apiKey: process.env.PRIVARO_API_KEY!,
  pipelineId: process.env.PRIVARO_PIPELINE_ID!,
});

const handler = new PrivaroCallbackHandler(privaro);

const llm = new ChatOpenAI({
  modelName: "gpt-4o",
  callbacks: [handler],
});

// PII tokenised automatically before reaching OpenAI
const response = await llm.invoke(
  "Revisa el contrato de María García, DNI 34521789X"
);

Vercel AI SDK — middleware

Works with generateText, streamText, and useChat.

import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";
import { PrivaroClient } from "privaro-sdk";
import { privaroMiddleware } from "privaro-sdk/adapters/vercel-ai";

const privaro = new PrivaroClient({
  apiKey: process.env.PRIVARO_API_KEY!,
  pipelineId: process.env.PRIVARO_PIPELINE_ID!,
});

const { text } = await generateText({
  model: openai("gpt-4o"),
  prompt: "Analiza el perfil de Carlos Gómez, DNI 45678901C",
  experimental_transform: privaroMiddleware(privaro),
});
// PII protected before OpenAI, de-tokenised in response

Agent runs

For multi-step agents, AgentRun shares token scope across turns — [NM-0001] always refers to the same person throughout the conversation.

import { AgentRun } from "privaro-sdk";

const run = new AgentRun({
  apiKey: process.env.PRIVARO_API_KEY!,
  pipelineId: process.env.PRIVARO_PIPELINE_ID!,
});

// Step 1 — protect user input
const step1 = await run.protect(
  "Review mortgage for Laura Sánchez, DNI 23456789D, income €2,340/mo"
);
const llmResponse = await openai.chat.completions.create({
  messages: step1.protected_messages,
  model: "gpt-4o",
});

// Step 2 — protect tool output (same run, same token scope)
const step2 = await run.protect("CIRBE score: 742 for DNI 23456789D");

// Restore original values in final response
const finalText = await run.reveal(llmResponse.choices[0].message.content!);

Module-level API

Mirrors the Python SDK pattern for simpler apps:

import privaro from "privaro-sdk";

privaro.init({
  apiKey: process.env.PRIVARO_API_KEY!,
  pipelineId: process.env.PRIVARO_PIPELINE_ID!,
});

const result = await privaro.protect("Patient DNI 34521789X...");

Error handling

import {
  PrivaroError,
  AuthError,
  PipelineNotFoundError,
  PolicyBlockError,
  RateLimitError,
  ProxyUnavailableError,
} from "privaro-sdk";

try {
  const result = await privaro.protect(prompt);
} catch (err) {
  if (err instanceof PolicyBlockError) {
    // Request blocked by privacy policy (mode: "block")
    return res.status(403).json({ error: "PII blocked" });
  }
  if (err instanceof AuthError) {
    // Invalid or expired API key
  }
  if (err instanceof RateLimitError) {
    // Implement exponential backoff
  }
  if (err instanceof ProxyUnavailableError) {
    // Network issue — proxy unreachable
  }
  // All errors extend PrivaroError
}

Detected entity types

| Type | Severity | Examples | |------|----------|---------| | full_name | medium | María López Fernández, Dr. García | | email | medium | [email protected] | | phone | high | 677 23 45 67, +34 612 345 678 | | dni | critical | 23456789D, 34521789X | | iban | critical | ES91 2100 0418 4502 0005 1332 | | credit_card | critical | 4111 1111 1111 1111 | | ssn | critical | 123-45-6789 | | health_record | critical | SIP/TSI card numbers | | ip_address | medium | 192.168.1.45 | | date_of_birth | medium | nacido 14/03/1978 | | session_id | low | sess_8f3a2b1c | | policy_number | high | nº póliza 00123456 |

Detection uses a hybrid engine: deterministic regex (Tier 1) + Microsoft Presidio with spaCy es_core_news_md (Tier 2). All detection runs server-side on the Railway proxy.


Environment variables

PRIVARO_API_KEY=prvr_...
PRIVARO_PIPELINE_ID=550e8400-e29b-41d4-a716-446655440000
PRIVARO_BASE_URL=https://privaro-proxy-production.up.railway.app/v1  # optional

Requirements

  • Node.js ≥ 18 — uses native fetch and crypto.randomUUID
  • Edge runtimes — Cloudflare Workers, Vercel Edge, Deno: all supported
  • CommonJS — bundled as both ESM and CJS

Links


MIT © iCommunity Labs