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

@priventai/core

v0.3.0

Published

AI agent runtime security: context-preserving tokenization, risk scoring, and policy enforcement

Readme

@priventai/core

Early Access. Privent is currently in private rollout. API keys are issued through our access process. Request access →

Runtime security for AI agents. Tokenize PII, secrets, and sensitive data before they reach LLMs; restore the originals only at trusted egress points.

"Customer: [email protected], Card: 4111-1111-1111-1111"
                          ↓ tokenize
"Customer: [EMAIL_001], Card: [CREDIT_CARD_001]"
                          ↓ LLM call
"Reply to [EMAIL_001] about [CREDIT_CARD_001]"
                          ↓ detokenize at trusted sink
"Reply to [email protected] about 4111-1111-1111-1111"

The LLM never sees raw secrets. Tokens are reversible, session-scoped, and deterministic within a session.


Features

  • Hybrid detection — regex patterns for EMAIL, PHONE, CREDIT_CARD, IBAN, SSN, API_KEY, JWT, AWS_KEY, IP, URL out of the box; pluggable ML extractor.
  • Session-scoped vault — same value maps to the same token within a session; cross-session tokens are randomized to block correlation attacks.
  • Deep detokenization — walks nested objects, arrays, and strings; cycle-safe.
  • Typed error taxonomyPriventError base class plus 9 subclasses, each with a retryable flag and JSON serialization that scrubs sensitive fields.
  • Resilient HTTP client — exponential backoff with jitter, idempotency keys, AbortController-based timeouts.
  • Fail-open by default — if Privent Cloud is unreachable, falls back to local regex detection rather than blocking traffic.
  • Dual ESM + CJS build with full TypeScript types.

Installation

npm install @priventai/core
# or
pnpm add @priventai/core
# or
yarn add @priventai/core

Requires Node.js 20+.


Quick Start

import { PriventClient } from '@priventai/core';

const client = new PriventClient({
  apiKey: process.env.PRIVENT_API_KEY, // request via https://www.privent.ai/request-access — without it, runs in regex-only mode
});

await client.withSession(async ({ vault }) => {
  const { tokenizedText } = await client.tokenizer.tokenize(
    'Customer: [email protected], Card: 4111111111111111',
    vault,
    { kinds: ['EMAIL', 'CREDIT_CARD'] },
  );
  // tokenizedText === "Customer: [EMAIL_001], Card: [CREDIT_CARD_001]"

  const llmResponse = await myLLM.invoke(tokenizedText);

  const restored = await client.tokenizer.detokenize(llmResponse, vault);
  return restored;
});
// vault.destroy() runs automatically in a finally block

API

PriventClient

Main entry point. Wires together a vault, tokenizer, risk scorer, policy engine, and audit logger.

const client = new PriventClient({
  apiKey?: string;                 // defaults to PRIVENT_API_KEY env var
  baseUrl?: string;                // default: https://api.privent.ai
  vaultFactory?: VaultFactory;     // default: in-memory
  tokenizer?: Tokenizer;           // default: HybridTokenizer (regex)
  riskScorer?: RiskScorer;
  policyEngine?: PolicyEngine;
  auditLogger?: AuditLogger;
  maxRetries?: number;             // default: 2
  timeout?: number;                // default: 30_000 ms
  failPolicy?: 'open' | 'closed';  // default: 'open'
});

client.withSession(fn)

Opens a session, gives fn a vault and IDs, and destroys the vault when fn resolves or throws.

const result = await client.withSession(async ({ vault, sessionId, traceId }) => {
  // vault: TokenVault — store/retrieve tokens
  // sessionId: per-session UUID
  // traceId: correlation ID for audit logs
  return doWork(vault);
});

Tokenizer

const { tokenizedText, entities } = await client.tokenizer.tokenize(text, vault, {
  kinds: ['EMAIL', 'PHONE'],
  allowList: ['[email protected]'],   // never tokenize
  denyList: ['internal-project-x'],    // always tokenize
  customPatterns: [
    { kind: 'PROJECT_CODE', regex: /PROJ-\d{4}/g, confidence: 0.95 },
  ],
});

Token format: [KIND_NNN] — e.g. [EMAIL_001], [CREDIT_CARD_003]

Built-in entity types:

| Kind | Confidence | Notes | |---|---|---| | EMAIL | 0.95 | RFC-pragmatic match | | PHONE | 0.80 | International + national formats | | CREDIT_CARD | 0.98 | Validated with Luhn checksum | | IBAN | 0.97 | Country-aware length check | | SSN | 0.90 | US format | | API_KEY | 0.88 | Common provider prefixes (sk-, ghp_, xoxb-, …) | | JWT | 0.98 | Three-segment base64url structure | | AWS_KEY | 0.99 | AKIA… access key IDs | | IP_ADDRESS | 0.85 | IPv4 | | URL | 0.90 | http/https |

detokenizeDeep(value, vault)

Walks any value (string, object, array, Map, Set) and replaces tokens with their originals.

import { detokenizeDeep } from '@priventai/core';

const restored = await detokenizeDeep(
  { email: '[EMAIL_001]', items: ['[PHONE_001]', 'plain text'] },
  vault,
);

Cycle-safe (uses WeakSet), depth-limited to 64, skips binary buffers, fast-paths strings without [.

Vault

import { InMemoryTokenVault } from '@priventai/core/vault/memory';

const vault = new InMemoryTokenVault('session-1');
await vault.store({ token: '[EMAIL_001]', value: '[email protected]', kind: 'EMAIL', ... });
const entry = await vault.retrieve('[EMAIL_001]');
const same = await vault.findByValue('[email protected]', 'EMAIL'); // determinism
await vault.destroy();

Normalization for determinism: EMAIL → lowercase + trim; PHONE, CREDIT_CARD, IBAN → digits only; others → trim.

Errors

import {
  PriventError,
  PriventConfigError,
  PriventAuthError,
  PriventRateLimitError,
  PriventAPIError,
  PriventNetworkError,
  PriventTimeoutError,
  PriventValidationError,
  PriventVaultFullError,
  PriventVaultDestroyedError,
} from '@priventai/core';

try {
  await client.tokenizer.tokenize(text, vault);
} catch (err) {
  if (err instanceof PriventError) {
    console.log(err.code, err.retryable, err.toJSON());
  }
}

toJSON() scrubs sensitive fields so errors are safe to log.


Security Properties

  • No persistence by default. The in-memory vault holds entries for the session lifetime only.
  • Cross-session randomization. Token IDs are not derived from input value — observing tokens across sessions reveals nothing.
  • Bounded vaults. Default cap of 10,000 entries per session prevents unbounded growth.
  • Sensitive fields scrubbed in error JSON. API keys, tokens, and entity values are stripped before serialization.
  • Idempotency keys on every Cloud request to make retries safe.

Documentation


License

Apache-2.0 © Privent AI

Questions? Contact us at [email protected].