LLM Data Guard: PII & Secret Redactor avatar

LLM Data Guard: PII & Secret Redactor

Pricing

from $1.50 / 1,000 document processeds

Go to Apify Store
LLM Data Guard: PII & Secret Redactor

LLM Data Guard: PII & Secret Redactor

Detect and redact PII (emails, phones, SSNs, Luhn-checked cards, IBANs, IPs, optional names/addresses) and secrets (API keys, tokens, private keys, high-entropy strings) in text, HTML or PDF before it reaches an LLM. Placeholder, mask or hash redaction with reversible map. No data retention.

Pricing

from $1.50 / 1,000 document processeds

Rating

0.0

(0)

Developer

Fairquery

Fairquery

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 hours ago

Last modified

Share

Finds and redacts PII and secrets in text, HTML and PDF before they reach an LLM, for $1.50 per 1,000 documents plus $0.20 per 1,000 findings. Error rows are free. Example: 1,000 support tickets with 2 findings each on average cost 1,000 × $0.0015 + 2,000 × $0.0002 = $1.90, plus Apify's $0.00005 Actor-start fee.

Fairquery Apify Actor that finds and redacts personal data (PII) and secrets in text, HTML and PDF documents before they are sent to an LLM, a vector store or a third-party API. Each document gets a risk level, a list of findings (type, offsets, masked preview) and, in redact mode, a clean output_text you can pass straight to your model. Placeholders are reversible, so you can put the original values back into the model's answer.

No data retention. The Actor never logs document content and writes nothing except the result rows in the run's default dataset and a counts-only RUN_SUMMARY. By default it also deletes the run's INPUT record when it finishes (purgeInputAfterRun). Raw values are not stored in findings unless you turn on includeFindingValues. You control the dataset; delete it (or the run) once you have read it.

When to use this Actor (LLM / tool selection)

Use it when an agent or pipeline needs to:

  • Strip emails, phone numbers, SSNs, card numbers, IBANs and IP addresses from prompts, chat logs, support tickets or CRM notes before LLM calls
  • Catch leaked credentials (AWS, GitHub, Slack, Stripe, OpenAI, Anthropic, Google, private keys, JWTs, password=...) in logs, code snippets and config files
  • Pseudonymise a dataset for RAG / fine-tuning with consistent placeholders ([EMAIL_1], [PERSON_2])
  • Restore real values in the LLM's answer (mode: "restore")
  • Audit a batch of documents for sensitive-data risk (mode: "detect")

Covers OWASP LLM Top 10 risk LLM02 Sensitive Information Disclosure at the input side. It is a pattern-and-validation engine, not a guarantee: always keep defense in depth.

What it detects

CategoryTypesValidation
PIIEMAIL, PHONE, SSN, CREDIT_CARD, IBAN, UK_NINO, IP_ADDRESSLuhn + issuer prefix for cards, mod-97 + country length for IBANs, libphonenumber for phones, SSN area/group rules
PII (opt-in)PERSON, LOCATION, STREET_ADDRESSOpen-source NER (compromise, English) and street-address patterns
SecretsPRIVATE_KEY, AWS_ACCESS_KEY, AWS_SECRET_KEY, GITHUB_TOKEN, GITLAB_TOKEN, SLACK_TOKEN, SLACK_WEBHOOK, STRIPE_KEY, GOOGLE_API_KEY, OPENAI_KEY, ANTHROPIC_KEY, HUGGINGFACE_TOKEN, NPM_TOKEN, SENDGRID_KEY, TWILIO_KEY, AZURE_STORAGE_KEY, JWT, URL_CREDENTIALSGitleaks-style rules
SecretsGENERIC_SECRET (api_key=…, token: …, password=…)Shannon-entropy threshold (minEntropy), placeholder words ignored
Secrets (opt-in)HIGH_ENTROPY_STRINGAny 20+ char random-looking token

Overlapping matches are resolved (secrets > cards/IBAN > SSN > email > IP > phone > address > names), so a card number is never also reported as a phone.

Redaction styles

redactionStyleExampleReversible
placeholder (default)Mail [EMAIL_1] or call [PHONE_1]Yes, with returnPlaceholderMap and mode: "restore"
maskj***@a***.com, **** **** **** 1111, AKIA****************No
hash[EMAIL:3f2a9c0d1b7e] (salted SHA-256 prefix)No; stable across runs if you set hashSalt

Input

FieldTypeDefaultDescription
textsstring[]– (sample texts are prefilled in the Console form)One document per entry
documents{id,text}[][]Documents with your own IDs
documentUrlsstring[][]Public txt/md/json/csv/HTML/PDF URLs (max 10 MB each)
modedetect | redact | restoreredact
redactionStyleplaceholder | mask | hashplaceholder
returnPlaceholderMapboolfalseAdds placeholder_map per row (contains originals!)
consistentPlaceholdersbooltrueSame value → same placeholder across documents
placeholderMapobject{}For restore mode
hashSaltsecret stringrandom per runFor hash style
detectPii / detectSecretsbooltrue
detectNames / detectAddresses / entropyScanboolfalseOpt-in detectors
minEntropynumber3.5Bits/char for generic secrets
defaultPhoneRegionstringUSFor numbers without + prefix
entityTypesstring[]allOnly report these types
allowListstring[][]Values never flagged
includeFindingValuesboolfalsePut raw values into findings
maxDocuments / maxCharsPerDocumentint1000 / 1,000,000Safety caps
purgeInputAfterRunbooltrueDelete the INPUT record at the end
{
"texts": ["Hi, I'm Jane (jane.doe@acme.com, +1 415-555-0132). Card 4111 1111 1111 1111.", "AWS key AKIAIOSFODNN7EXAMPLE"],
"mode": "redact",
"redactionStyle": "placeholder",
"returnPlaceholderMap": true
}

Output

One row per document (type: "document") plus machine-readable type: "error" rows.

{
"schema_version": "1.0.0", "type": "document", "id": "text-1", "source": "text", "chars": 78, "mode": "redact",
"finding_count": 3, "risk_level": "high",
"counts_by_type": { "EMAIL": 1, "PHONE": 1, "CREDIT_CARD": 1 },
"findings": [
{ "type": "EMAIL", "category": "pii", "rule": "email", "confidence": "high", "start": 14, "end": 31, "length": 17, "preview": "j***@a***.com", "replacement": "[EMAIL_1]" }
],
"output_text": "Hi, I'm Jane ([EMAIL_1], [PHONE_1]). Card [CREDIT_CARD_1].",
"placeholder_map": { "[EMAIL_1]": "jane.doe@acme.com", "[PHONE_1]": "+1 415-555-0132", "[CREDIT_CARD_1]": "4111 1111 1111 1111" }
}

risk_level: high = any secret or card/SSN/IBAN/NI number; medium = other confident PII; low = only low-confidence (NER/entropy) hits; none.

Restore after the LLM answers:

{ "mode": "restore", "texts": ["Dear [EMAIL_1], your card ending [CREDIT_CARD_1]…"], "placeholderMap": { "[EMAIL_1]": "jane.doe@acme.com" } }

Error codes: INPUT_EMPTY, MAX_DOCUMENTS_EXCEEDED, PLACEHOLDER_MAP_MISSING, DOCUMENT_FETCH_FAILED (error rows are never charged).

RUN_SUMMARY (key-value store) holds counts per type, charged events and settings only, never text.

Pricing

EventPriceWhen
document-processed$0.0015Each document scanned (or restored)
finding$0.0002Each PII or secret finding reported
apify-actor-start$0.00005Once per run, per GB of memory (Apify default event)

Error rows (INPUT_EMPTY, MAX_DOCUMENTS_EXCEEDED, PLACEHOLDER_MAP_MISSING, DOCUMENT_FETCH_FAILED) are never charged.

Worked example: 1,000 support tickets, 2,000 findings in total: 1,000 × $0.0015 + 2,000 × $0.0002 = $1.50 + $0.40 = $1.90, plus $0.00005. A clean document with no findings costs $0.0015.

To cap spend, set a maximum cost per run in the run options; the Actor stops cleanly at the limit. entityTypes limits which types are reported (and charged as findings); maxDocuments caps documents per run. Prices are from the Store pricing tab (October 2026).

Memory / runtime

Runs at a fixed 512 MB (default and maximum; enough for NER), no browser, no proxy. Regex detectors process roughly 1–5 MB of text per second; NER (detectNames) is slower, so split very big batches into several runs. PDFs are parsed with unpdf (text layer only, no OCR).

MCP / Apify tools

Call from agents via Apify MCP with Actor fairquery/llm-data-guard-pii-secrets:

{ "actor": "fairquery/llm-data-guard-pii-secrets", "input": { "texts": ["..."], "mode": "redact" } }

Works well after

  • Website Content Crawler: scrub crawled pages before you index them in a vector store or send them to an LLM.
  • Exports of support tickets, chat logs or CRM notes: run them through mode: "redact" first, call your model, then put the real values back with mode: "restore".

Troubleshooting

SymptomCause and fix
Run ends with only an INPUT_EMPTY rowNo texts, documents or documentUrls. The sample texts in the Console form are prefill only and are not sent with API calls.
DOCUMENT_FETCH_FAILEDThe URL was unreachable, over 10 MB or not a supported type. These rows are free. Scanned PDFs have no text layer, and there is no OCR.
PLACEHOLDER_MAP_MISSING in restore modePass the placeholderMap returned by the redact run (returnPlaceholderMap: true).
Too many findings (false positives)Add known-safe values to allowList, raise minEntropy, keep entropyScan off, or limit entityTypes.
Names or addresses not detecteddetectNames and detectAddresses are opt-in and English-focused. Turn them on (they are slower; split very big batches).

FAQ

Is document content stored?

Content is never logged. Results go only to your run's dataset, RUN_SUMMARY holds counts only, and the INPUT record is deleted at the end by default (purgeInputAfterRun). Delete the dataset when you no longer need it.

Can I get the original values back after the LLM answers?

Yes. Use redactionStyle: "placeholder" with returnPlaceholderMap: true, then run mode: "restore" with that map.

Does it catch everything?

No. It is a pattern-and-validation engine (checksums, issuer prefixes, Gitleaks-style rules). Unusual formats, non-English names and images can slip through. Use it as one layer of defence.

How much does it cost?

$0.0015 per document plus $0.0002 per finding, and a $0.00005 start fee. Error rows are free.

Can I scan text without sending it to Apify?

Yes. The Fairquery MCP server (npx -y @fairquery/agent-trust-mcp) has free pii_scan_text and pii_redact_text tools that run locally. This Actor adds names and addresses, URLs, PDFs and restore mode.

Fairquery family

Other Fairquery tools on the Apify Store. Each one returns structured rows with machine-readable error codes, and error rows are never charged:

All Fairquery Actors: https://apify.com/fairquery

Kits & templates

Optional guides from Fairquery for wiring this Actor into agents and automations (the Actor works fine without them):

Disclaimer

Pattern-based detection finds most but not all sensitive data: unusual formats, non-English names, images and scanned PDFs (no OCR) can slip through, and some matches are false positives. Use it as one layer of a data-protection program, not as a compliance certification. Only process data you are allowed to process.