πŸ”¬ Redact personal data from any item with data tables, audit log and Discord

⚑ 3 views Β· πŸ”¬ Document Extraction & Analysis

Description

Quick overview

This sub-workflow redacts common personal data from any incoming item using a policy stored in n8n Data Tables, returns a redacted payload plus a detection report to the calling workflow, and writes an audit entry to a redaction_log table (with an optional Discord self-test notification).

How it works

  1. Triggers when another n8n workflow calls it via an Execute Workflow Trigger and passes in an item (optionally with payload and requested_by).
  2. Reads the current redaction settings from the redaction_policy n8n Data Table and attaches them to each incoming item.
  3. Scans all strings in the payload and redacts detected email addresses, IBANs (mod-97 validated), payment cards (Luhn validated), phone numbers, and IPv4 addresses using the configured mode (mask, pseudonymise, or remove).
  4. Collects a report of how many values were redacted per detector and lists any β€œunclassified” candidates (like long digit runs or possible names) without changing them.
  5. Inserts an audit record into the redaction_log n8n Data Table with counts, mode, requester, and payload size (but never the original values).
  6. Returns the redacted payload and the redaction report back to the calling workflow.

Setup

  1. Run the β€œSet Up And Self Test (run once)” path to create the redaction_policy and redaction_log n8n Data Tables and seed the default policy.
  2. If you plan to use pseudonymise mode, set a strong pseudonym_key value in the redaction_policy table (the workflow refuses to pseudonymise while it is empty).
  3. (Optional) Add a Discord Webhook credential to post the self-test summary, or disable/remove the Discord step if you don’t want notifications.
  4. From your other workflows, call this sub-workflow and pass either { payload, requested_by } or send the record directly as the item JSON.

Requirements

Customization

Additional info

This is a tool other workflows call, not a workflow that runs on its own, and it is deliberately model-free. A redactor that sent personal data to a model in order to decide what counts as personal data would be adding a confident opinion about text it cannot verify, at the exact moment you least want one. Everything here either matches a validated pattern or it does not.

The part worth reading twice is what it does when it cannot do its job. An empty policy table refuses, and says so: an empty policy is not evidence that there is nothing to redact. Pseudonymise with no key refuses, and says why. In both cases the item comes back untouched with values_redacted at zero, the refusal is written to the audit log with its reason, and nothing is half-redacted. That was tested by deleting all eight policy rows and by running pseudonymise with the shipped empty key.

Validation is the difference between this and a regular expression. 4111 1111 1111 1111 is redacted as a card. 4111111111111112 is one digit off, fails Luhn, and is left in place, because it is far more likely to be an order number. DE89370400440532013000 is redacted as an IBAN and DE89370400440532013001 fails mod-97 and survives. A 21 digit reference number is past the E.164 limit of 15 and is not a phone number. Every one of those is a look-alike probe in the shipped self test, and they matter more than the positive cases: a detector that fires on everything turns every invoice number into a redacted card.

What it cannot do is more important than what it can. Personal names are not detected, because no pattern distinguishes a person from a place or a product, and pretending otherwise would be the worst kind of false confidence in a tool like this. Instead, anything that looked like it might identify somebody is returned as an unclassified candidate, and every answer carries the sentence that a result with nothing redacted is not evidence that the item holds no personal data. Names in a non-Latin script are missed entirely.

The audit log holds counts and detector names, never the values. A redactor that wrote the originals into a log table would have redacted nothing, just moved the problem, so redaction_log records when, who asked, which mode, payload_chars for the size of the item once serialised, how many values were replaced, how many were unclassified, the per-detector counts and the reason. That is enough to answer how much personal data is flowing through a pipeline without storing any of it.

Run Set Up And Self Test once and it does three things: creates the two tables with typed columns, loads the default policy, and pushes eight known probes through the same detector every caller uses, then posts the result. Five of the probes must be redacted and three must not. If someone later loosens a pattern, the self test says so rather than the change being noticed in production.

Known limits, stated plainly. Personal names, postal addresses and dates of birth are not detected. Non-Latin scripts are missed. Pseudonym tokens are stable only while the key is unchanged, and there is no rotation path. Nothing has been tested above a few hundred characters per item, and two callers writing the audit log at the same instant was never tried. The detectors are ordered so the validated ones consume their digits before the loosest one runs, which is a real dependency: adding a detector at the wrong position in that list could change what the others see.

πŸ”— Nodes Used

Discord, Execute Workflow Trigger, Data table

πŸ“₯ Import

Download workflow.json and import into n8n: Workflow menu β†’ Import from File

πŸ“– Importing guide Β· πŸ”‘ Credential setup