redactum
v1.1.0
Published
Comprehensive PII redaction library for AI applications with framework adapters for LangChain, LlamaIndex, Haystack, OpenAI SDK, Anthropic SDK, and Vercel AI SDK
Maintainers
Readme
⛨ redactum - automated PII & secret redaction
What It Does
Fast, zero-dependency PII redaction library for TypeScript and JavaScript that automatically removes sensitive data before it leaves your stack.
Redactum protects you and your users by redacting:
- 👤 Personal information (emails, phone numbers, SSNs)
- 💳 Financial data (credit cards, bank accounts)
- 🔑 Developer secrets (API keys, database URLs, JWT tokens)
- 🏗️ Infrastructure details (IP addresses, AWS credentials)
190+ built-in patterns across 32 categories for comprehensive detection of personal, financial, and technical sensitive data.
Installation
pnpm install redactumQuick Start
import { redactum } from "redactum";
const userMessage = `Errors found in cloudwatch
ERROR: Failed to connect to database
DEBUG: DATABASE=postgres://admin:u$k9!fR2@qLx2@db:5432/db`;
const result = redactum(userMessage);Errors found in cloudwatch
ERROR: Failed to connect to database
DEBUG: DATABASE=postgres://[REDACTED]:[REDACTED]@db:5432/dbProvider Integrations
Redactum works seamlessly with popular AI SDKs:
OpenAI
import { createOpenAIAdapter } from "redactum/providers";
import OpenAI from "openai";
const adapter = createOpenAIAdapter();
const openai = adapter.createClientWrapper(new OpenAI());
const completion = await openai.chat.completions.create({
model: "gpt-4",
messages: [
{
role: "user",
content: `Errors found in cloudwatch
ERROR: Failed to connect to database
DEBUG: DATABASE=postgres://admin:u$k9!fR2@qLx2@db:5432/db`,
},
],
});Anthropic
import { createAnthropicAdapter } from "redactum/providers";
import Anthropic from "@anthropic-ai/sdk";
const adapter = createAnthropicAdapter();
const anthropic = adapter.createClientWrapper(new Anthropic());
const message = await anthropic.messages.create({
model: "claude-3-5-sonnet-20241022",
max_tokens: 1000,
messages: [
{
role: "user",
content: "Process this: API_KEY=sk_live_4eC39HqLyjWDarjtT1zdp7dc",
},
],
});LangChain
import { createLangChainAdapter } from "redactum/providers";
import { Document } from "@langchain/core/documents";
const adapter = createLangChainAdapter();
const transformer = adapter.createDocumentTransformer();
const docs = await transformer([
new Document({
pageContent: "Contact: [email protected], Phone: +44 20 7946 0958",
}),
]);Vercel AI
import { createVercelAIAdapter } from "redactum/providers";
import { openai } from "@ai-sdk/openai";
const adapter = createVercelAIAdapter();
const { streamText } = adapter.createStreamingWrapper();
const result = await streamText({
model: openai("gpt-4"),
prompt: "Credit card: 4111-1111-1111-1111",
});LlamaIndex
import { createLlamaIndexAdapter } from "redactum/providers";
import { TextNode } from "llamaindex";
const adapter = createLlamaIndexAdapter();
const transformer = adapter.createNodeTransformer();
const nodes = await transformer.transform([
new TextNode({
text: "SSN: 123-45-6789",
}),
]);Usage
Basic Redaction
import { redactum } from "redactum";
const result = redactum("Email me at [email protected]");
console.log(result.redactedText);Custom Replacement
const result = redactum("Email: [email protected]", {
replacement: "***",
});
const result = redactum("Email: [email protected]", {
replacement: (match, category) => `[${category}]`,
});Selective Redaction
const result = redactum("Email: [email protected], SSN: 123-45-6789", {
policies: ["EMAIL_ADDRESS", "SSN"],
});Custom Patterns
import { PolicyCategory } from "redactum";
const result = redactum("Employee: EMP-123456", {
customPolicies: [
{
name: "EMPLOYEE_ID",
pattern: /EMP-\d{6}/g,
category: PolicyCategory.CUSTOM,
},
],
});Length Preservation
const result = redactum("Stripe: sk_live_4eC39HqLyjWDarjtT1zdp7dc", {
preserveLength: true,
replacement: "*",
});Batch Processing
import { redactumBatch } from "redactum";
const messages = [
"Support ticket from [email protected]",
"Customer callback: +44 20 7946 0958",
"Payment failed: 4111-1111-1111-1111",
];
const results = await redactumBatch(messages);
const redactedMessages = results.map((result) => result.redactedText);Error Handling
import { redactumValidateOptions, PolicyCategory } from "redactum";
try {
redactumValidateOptions({
policies: ["EMAIL_ADDRESS", "PHONE_NUMBER_UK"],
customPolicies: [
{
name: "EMPLOYEE_ID",
pattern: /EMP-\d{6}/g,
category: PolicyCategory.CUSTOM,
},
],
});
} catch (error) {
console.error("Invalid configuration:", error.message);
}API
Core Functions
redactum(text, options?)- Main redaction functionredactumBatch(texts[], options?)- Batch process multiple textsredactumFromConfig(text, configOptions?)- Load from config filecreateRedactum(options?)- Create stateful instance
Validation Functions
redactumValidateOptions(options)- Validate configurationredactumValidatePolicy(pattern)- Validate custom policy
Utility Functions
redactumCalculateEntropy(text)- Shannon entropy (0-8)redactumLooksLikeSecret(text, minLength?, threshold?)- Heuristic secret detectionredactumGetAllPatterns()- All built-in policiesredactumGetPatterns(options?)- Patterns for configredactumGetEnabledPolicies(options?)- Enabled policy namesredactumGetEnabledCategories(options?)- Enabled categories
Contributing
Contributions, issues, and feature requests are welcome. If you would like to get involved, please open an issue or submit a pull request to help improve the project.
License
This project is released under the MIT License. Created and maintained by Alex Whinfield.
