> ## Documentation Index
> Fetch the complete documentation index at: https://docs.unstructured.io/llms.txt
> Use this file to discover all available pages before exploring further.

# PII redaction

> Detect and optionally redact personally identifiable information in element text using Microsoft Presidio, running entirely in-process and airgapped.

<Note>
  The following information applies only to dedicated instance and in-VPC deployments of [Unstructured Business](/business/overview).

  Contact your Unstructured account team or open a ticket in the [Unstructured Support Portal](https://support.unstructured.io/) to have it enabled for your deployment.
</Note>

The **PII Redaction** node detects personally identifiable information (PII) in each element's text. Depending on the mode you choose, it redacts the detected PII, records what was found, or both. Detection is powered by [Microsoft Presidio](https://microsoft.github.io/presidio/).

The node runs entirely in-process and airgapped: the named-entity recognition (NER) model is baked into the node's image, and Presidio makes no outbound network calls at runtime. Element text never leaves the node to any external service.

<Warning>
  PII detection is probabilistic and is not a guarantee. It relies on statistical named-entity recognition (NER) and pattern matching, so it will produce both false positives (text incorrectly flagged as PII) and false negatives (PII that is not detected). NER-based detection is English-only.

  Do not use this node as your sole privacy or compliance mechanism. You are responsible for validating its output against your own regulatory and compliance requirements. Unstructured is not responsible for misclassifications, or for any PII that this node fails to detect or redact. For details, see [Limitations](#limitations).
</Warning>

## Workflow placement

The PII Redaction node can be placed anywhere in a workflow after the **Partitioner** node and before the destination. The recommended placement is immediately after the **Partitioner** node, so that PII is redacted before any downstream node processes the text. For example:

```
Source → Partitioner → PII Redaction → Chunker → Embedder → Destination
```

The same placement rule applies to any downstream node that processes element text, including Prompter-based enrichment nodes. Most of these enrichment nodes, such as image description, table description, and generative OCR, run before chunking. Named entity recognition (NER) is an exception: it runs after chunking, alongside the Chunker and Embedder nodes shown here.

<Note>
  The airgap applies to this node, not to the workflow as a whole.

  If the **Partitioner** node uses a VLM-based strategy, it sends the original, unredacted document to the external VLM provider during partitioning, before this node runs.

  Downstream nodes such as **Embedder** and enrichment nodes also send element text to their providers. Placing PII Redaction before them ensures they receive only redacted text.

  For a fully airgapped pipeline, every node in the workflow must be airgapped, not just this one.
</Note>

## How it works

The node accepts the standard stream of document elements and outputs the same stream, one element out for every element in. For every element that contains text, the node:

1. Runs Presidio's analyzer over the text.
2. Keeps only the detections whose confidence score is at or above the confidence threshold.
3. Depending on the redaction mode, rewrites the text, records the findings in the element's metadata, or both.

Entity selection is intentionally not configurable: the node always runs all of Presidio's registered recognizers, so detection covers the full range Presidio supports rather than a limited subset. Detected entity types include `PERSON`, `EMAIL_ADDRESS`, `PHONE_NUMBER`, `CREDIT_CARD`, `US_SSN`, `IP_ADDRESS`, `IBAN_CODE`, `LOCATION`, and more. For the full list, see [Supported entities](https://microsoft.github.io/presidio/supported_entities/) in the Presidio documentation.

## Limitations

Understand these limitations before you rely on this node's output, and validate its results against your own regulatory and compliance requirements:

* **Detection is probabilistic, not guaranteed.** PII detection uses statistical NER models and pattern matching. No configuration of this node detects all PII in all documents, and some text that is not PII will be flagged as PII. Redacted output is not certified to be free of PII.
* **NER is English-only.** Entity types that depend on the NER model, such as `PERSON` and `LOCATION`, are detected only in English text. Pattern-based entity types, such as email addresses, credit card numbers, and IP addresses, are detected regardless of language.
* **The confidence threshold is an accuracy tradeoff.** Raising the threshold reduces false positives but increases missed PII; lowering it catches more PII but flags more non-PII text. No threshold value eliminates both kinds of error.
* **The entity types are fixed.** The node always runs all of Presidio's registered recognizers. You cannot add custom entity types, restrict detection to specific entity types, or tune individual recognizers.
* **This node is not a compliance mechanism on its own.** It is a best-effort redaction aid. Do not rely on it as your sole control for meeting privacy or regulatory obligations such as GDPR, CCPA, or HIPAA; validate its output as part of your own compliance process.

## Redaction mode setting

Specifies whether the node rewrites element text, records its findings in element metadata, or both. A single mode controls both behaviors, so there is no contradictory combination.

To specify this setting, choose one of the following for **Mode**:

* **Detect only**: Leave the text unchanged, and only record the findings in each element's `metadata.pii_detections` field. This is a non-destructive audit pass.
* **Redact + audit** (default): Anonymize the detected PII in the text, and also record the findings in `metadata.pii_detections` as an audit trail of what was redacted.
* **Redact only**: Anonymize the detected PII in the text, and write no metadata. Nothing about the detected PII is persisted.

## Anonymization method setting

Specifies how each detected PII span is rewritten when the redaction mode redacts text. This setting has no effect when **Mode** is set to **Detect only**.

To specify this setting, choose one of the following for **Anonymization method**:

* **Replace with `<TYPE>` tag** (default): Substitute the entity type for the detected value, for example `<PERSON>` or `<EMAIL_ADDRESS>`. The output stays readable and shows what kind of PII was removed.
* **Remove entirely**: Delete the detected span from the text.
* **Mask characters**: Overwrite each character of the detected span with the mask character.
* **Hash (keyed HMAC-SHA256 pseudonymization)**: Replace the detected value with a deterministic HMAC-SHA256 token, keyed with the hash secret. Under the same secret, the same value maps to the same token across every element and document, which is useful for correlating or joining on a value without revealing it. This method requires a hash secret; a redacting mode with **Hash** selected and no secret available fails at startup rather than silently producing unkeyed digests.

<Warning>
  Hashing is pseudonymization, not strong anonymization. Without the secret, recovering a value from its token is computationally infeasible, but anyone holding the secret can confirm a guessed value against its token, and tokens remain linkable across documents by design. If the original value must be unrecoverable by everyone, use **Replace** or **Remove** instead.
</Warning>

## Confidence threshold setting

Specifies the minimum detection confidence score, from `0` to `1`, that a finding must have for the node to act on it. A higher threshold produces fewer false positives but misses more entities; a lower threshold catches more entities but produces more false positives.

To specify this setting, specify a number between `0` and `1` for **Confidence threshold**. The default is `0.4`, which lets Presidio's standard recognizers (including phone numbers, which Presidio scores at exactly `0.4`) fire out of the box.

## Mask character setting

Specifies the single character used to overwrite PII when the anonymization method is **Mask characters**. This setting has no effect for any other anonymization method.

To specify this setting, specify a single character for **Mask character**. The default is `*`.

## Hash secret setting

Specifies the secret key for the **Hash** anonymization method. Tokens are HMAC-SHA256 keyed with this value: the same secret yields the same token for the same value, so keep the secret stable across the workflows whose outputs you want to correlate, and treat it like a credential.

To specify this setting, specify a string for **Hash secret**. Deployments can instead set a default for all PII Redaction nodes through the `PII_HASH_SECRET` environment variable on the node's deployment; the per-node setting takes precedence when both are set.

This setting is required when the anonymization method is **Hash** and the redaction mode redacts text (**Redact + audit** or **Redact only**). If no secret is available from either the setting or the environment variable, the node fails at startup. In **Detect only** mode no text is rewritten, so no secret is needed.

## PII detection metadata

When the redaction mode records findings (**Detect only** or **Redact + audit**), each affected element's metadata gets a `pii_detections` field containing a list of findings:

```json theme={null}
{
    "metadata": {
        "pii_detections": [
            {
                "entity_type": "PERSON",
                "start": 11,
                "end": 21,
                "score": 0.85
            },
            {
                "entity_type": "EMAIL_ADDRESS",
                "start": 40,
                "end": 62,
                "score": 1.0
            }
        ]
    }
}
```

The `start` and `end` offsets are character positions in the *original* text, because detection runs before any rewrite. In the redact modes, the offsets describe what was there before redaction, not positions in the redacted output.

## Add a PII Redaction node

To add a PII Redaction node to a workflow, add it after the **Partitioner** node in the workflow designer, and select **PII Redaction**.

For **Unstructured API** users, add a [PII Redaction node](/api-reference/workflow/nodes/pii-redactor/pii-redactor) as either an object in a `workflow_nodes` array (for curl) or a `WorkflowNode` in a `WorkflowNodes` collection (for Python) whenever you [create a workflow](/api-reference/api/workflow/create-workflow), [update a workflow](/api-reference/api/workflow/update-workflow), or [create an on-demand workflow job](/api-reference/api/job/create-job).

If you don't have access to this node, see the [PII detection example](/examplecode/tools/pii) using the Microsoft Presidio SDK directly. The Unstructured open source library does not support PII redaction either.

## Questions? Need help?

Contact your Unstructured account team or open a ticket in the [Unstructured Support Portal](https://support.unstructured.io/).
