Content-stream PDF redaction No recoverable text
v0.1.1MITNode.js / LambdaZero-dependency core
Your PDF is processed in memory on our server, never written to disk or logged, and discarded the moment the response is sent. No third parties, no AI, no tracking of file contents.

True PDF
redaction.

scrubzero removes text operators from the page content stream before drawing the visual bar. No hidden layers. No recoverable text. Built for server-side use in Node.js and AWS Lambda.

npmGitHub
01Sandbox

Upload a PDF, enter a search pattern (plain text or /regex/flags), download the redacted result.

01 — Upload PDF

02 — Search pattern

Plain text or /regex/flags — all matches on every page are redacted

03 — Bar color

#111111
02Scanned PDFs

A scan is an image — a bar drawn over it removes nothing. This tool OCRs the pages, burns opaque boxes into the pixels, and rebuilds the PDF from the flattened images, so the original content is destroyed. It runs entirely in your browser — the file never leaves your device.

Runs entirely in your browser. The scan is rendered, read, and rebuilt on this device — it is never uploaded. The redacted pages are flattened images, so the original pixels are destroyed, not just covered.

01 — Upload a scanned PDF

02 — What to redact

#000000 · box color
03How it works
01Content stream scrubbing

pdfjs-dist extracts text items with positions. For each match, scrubzero locates the BT/ET block in the raw content stream bytes, finds the text-drawing operators, and blanks their string arguments. The glyph data is gone before the bar is drawn.

02Visual bar overlay

After scrubbing, pdf-lib draws a filled rectangle over the region using the specified color (default black). The bar is a genuine visual layer on top of now-empty space — there is no text underneath to recover.

03Metadata sanitization

DocInfo fields (Title, Author, Subject, Keywords, Producer, Creator) are wiped and timestamps reset. The XMP metadata stream is removed from the document catalog. Enabled by default, disable with sanitizeMetadata: false.

04Audit manifest

When generateManifest: true, each redaction entry is recorded with page number, bounding box, timestamp, optional redactor ID, basis code, and SHA-256 hashes of both the input and output PDF for chain-of-custody compliance.

05Scanned pages are flagged, then handled

Redaction works on the text layer. A scanned or image-only page has no text to remove, so a bar there only covers the pixels — it does not delete them. scrubzero detects this and returns a warning instead of a false all-clear, then the Scanned PDFs tool above OCRs the page, burns the boxes into the pixels, and rebuilds the file from flattened images — all in your browser, so the scan never leaves your device.

04Usage

Search and redact by text pattern

import { searchAndRedact } from '@liiift-studio/pdf-redact'
import { readFile, writeFile } from 'node:fs/promises'

const pdf = await readFile('document.pdf')
const result = await searchAndRedact(pdf.buffer, [
  { pattern: /John Smith/g, label: 'REDACTED' },
  { pattern: /\d{3}-\d{2}-\d{4}/g, label: 'SSN' },
])

await writeFile('redacted.pdf', result.pdf)
console.log(`${result.redactedCount} regions redacted`)

Redact specific regions by coordinate

import { redact } from '@liiift-studio/pdf-redact'

const result = await redact(pdf.buffer, [
  { page: 1, x: 72, y: 140, width: 200, height: 18 },
  { page: 2, x: 72, y: 200, width: 150, height: 18 },
])

Entity patterns — SSN, phone, email, credit card, and more

import { redactEntities } from '@liiift-studio/pdf-redact'

const result = await redactEntities(pdf.buffer, [
  'ssn', 'phone', 'email', 'credit-card',
])

Audit manifest with FOIA exemption codes

const result = await redact(pdf.buffer, regions, {
  generateManifest: true,
  redactorId: 'agent-smith',
  basisCode: 'b6',           // FOIA Exemption 6
  addRedactionMarkers: true, // print exemption code in bar
})

CLI

npx @liiift-studio/pdf-redact search document.pdf "John Smith" --output redacted.pdf
npx @liiift-studio/pdf-redact search document.pdf "/\d{3}-\d{2}-\d{4}/g" --color #1a1a1a
npx @liiift-studio/pdf-redact entities document.pdf --types ssn,phone,email
npx @liiift-studio/pdf-redact verify redacted.pdf

RedactOptions

OptionDefaultDescription
sanitizeMetadatatrueWipe DocInfo fields and remove XMP metadata stream
flattenAnnotationstrueFlatten annotation layers before redacting
addRedactionMarkersfalseRender label or exemption code inside the bar
generateManifestfalseAttach a JSON audit manifest with SHA-256 hashes
redactorIdundefinedOperator ID recorded in the manifest
basisCodeundefinedFOIA basis code (e.g. 'b6') rendered in the bar when markers are on