JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 29
  • Score
    100M100P100Q73243F
  • License Apache-2.0

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

Package Exports

  • @priventai/core
  • @priventai/core/contracts
  • @priventai/core/package.json
  • @priventai/core/vault/memory

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: alice@acme.com, 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 alice@acme.com 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: alice@acme.com, 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: ['noreply@system.com'],   // 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: 'a@b.com', kind: 'EMAIL', ... });
const entry = await vault.retrieve('[EMAIL_001]');
const same = await vault.findByValue('a@b.com', '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 hello@privent.ai.