PII redaction
PII redaction strips personally identifiable information from text before it reaches an LLM provider or a log, so raw values never leave the trust boundary. Caisson's guardrails package detects email addresses, US Social Security numbers, Luhn-valid credit card numbers, and phone numbers, then masks, hashes, or reversibly tokenizes each match: four regex-based detector classes, not exhaustive PII coverage.
In code
export type RedactMode = "mask" | "hash";
export type PiiMode = RedactMode | "tokenize";
/**
* Irreversibly redact every PII hit. `mask` → `[KIND]`; `hash` → `[KIND:<12-hex>]` (stable per
* value). Returns the redacted text plus metadata-only matches (no raw value re-exposed downstream).
*/
export function redactPii(
text: string,
mode: RedactMode,
): { redacted: string; matches: PiiMatch[] } {
const matches = detectPii(text);
const replace =
mode === "mask"
? (m: PiiMatch): string => `[${m.kind.toUpperCase()}]`
: (m: PiiMatch): string =>
`[${m.kind.toUpperCase()}:${sha256Hex(m.value).slice(0, 12)}]`;
return { redacted: rewrite(text, matches, replace), matches };
}How it holds
Four regex-based detector classes, deterministically resolved
detectPii runs an email, SSN, Luhn-validated credit-card, and phone regex over the text, then resolves any overlapping matches by earliest start, then longest span, then kind name, so the same input always redacts identically across runs.
Three modes behind one detector
redactPii covers mask ([KIND]) and hash ([KIND:<12-hex>], stable per value so equal inputs correlate without exposure); tokenizePii is the third mode, sealing the original via field-crypto instead of replacing it with a fixed placeholder.
Tokenize is the sole reversible path
tokenizePii seals each hit with field-crypto's sealField under a bound AAD column context and swaps in an opaque [[PII:kind:i]] placeholder; detokenizePii opens the envelope under the same tenant context to restore it, and silently skips any placeholder a provider dropped rather than re-injecting it blind.
A separate path redacts secret-bearing keys, not PII text
@caisson/kernel's redactValue walks an object and masks any property whose key name matches a secret allowlist (password, token, apiKey, and similar), a different mechanism for structured payloads, kept distinct from pii.ts's free-text PII detection.