# Microsoft Presidio

Presidio is Microsoft's open-source toolkit for detecting and anonymising personal data in text and images, widely used to protect PII in LLM pipelines.

## Overview

Presidio is an open-source toolkit from Microsoft for finding and removing personally identifiable information (PII), such as names, phone numbers, email addresses, credit card numbers and national identifiers. It has two main steps. The analyzer scans text and reports where it thinks PII appears and how confident it is. The anonymizer then replaces, masks, hashes, encrypts or removes those pieces. Extra packages handle images and structured data.

In LLM applications, Presidio is often placed on both sides of the model. Before a prompt goes to a hosted model, PII is masked so it never leaves the organisation. Before logs and traces are stored, PII is removed so that monitoring data is safer to keep. It is also used outside AI, for example to clean documents before analysis or sharing.

An everyday analogy: a press office preparing documents for release. One person goes through with a highlighter, marking every name and phone number. A second person then blacks out or replaces each highlighted item according to the rules. Presidio's analyzer is the highlighter; the anonymizer is the black marker.

## What it is

| Part | What it does | Notes |
|---|---|---|
| Analyzer | Detects PII entities in text and returns their positions, types and scores | Package `presidio-analyzer` |
| Recognizers | Individual detectors for one or more entity types | Regex patterns, checksums, context words, NER models, deny lists |
| NLP engine | Runs named-entity recognition and tokenisation | spaCy by default; Stanza and transformer models supported |
| Context enhancement | Raises scores when words such as "phone" appear nearby | Reduces false positives on bare numbers |
| Anonymizer | Applies operators to the detected spans | Package `presidio-anonymizer` |
| Operators | Replace, redact, mask, hash, encrypt, keep or custom functions | Configurable per entity type |
| Deanonymizer | Reverses reversible operators such as encryption | Needs the key |
| Image redactor | Finds PII in images with OCR and blacks it out | Package `presidio-image-redactor`, including DICOM medical images |
| Structured | Analyses and anonymises tables and semi-structured data | Package `presidio-structured` |

Presidio is released under the MIT licence. Its components can be used as Python libraries or run as services, for example in Docker containers.

## Where it came from

Presidio was developed by Microsoft and published as open source on GitHub. Early versions were built as a set of services for scanning and anonymising data. Its second major version reorganised the project around separate Python packages, published on PyPI, for the analyzer and anonymizer, which made it far easier to embed in applications and notebooks.

The project has since added more recognizers for country-specific identifiers, support for several NLP engines including transformer models, the image redactor with support for medical DICOM images, structured data support and integrations with frameworks such as LangChain and NeMo Guardrails. Recent versions also support language-model-based PII detection through Google's LangExtract library, with local models through Ollama or hosted models through Azure OpenAI.

Presidio is a toolkit, not a compliance product. Microsoft's documentation stresses that automated detection can miss PII, so additional safeguards are needed.

## How it works

### 1. Analyse

The analyzer receives text and a language. It runs the NLP engine to find entities such as people, places and organisations, then runs each registered recognizer. Pattern recognizers use regular expressions, often with checks such as the Luhn checksum for card numbers. Context-aware recognizers look for supporting words nearby. Each finding gets an entity type, start and end positions and a confidence score between 0 and 1.

### 2. Filter

You choose which entity types to look for and a minimum score. Allow lists stop known safe values, such as your company's support number, from being flagged.

### 3. Anonymise

The anonymizer takes the text and the findings and applies an operator per entity type:

- Replace with a placeholder such as `<PERSON>`.
- Redact by removing the text.
- Mask some characters, for example all but the last four digits.
- Hash with a one-way function, so equal values stay linkable.
- Encrypt with a key, so values can be restored later.
- Custom functions, for example replacing names with realistic fake ones.

```python
from presidio_analyzer import AnalyzerEngine
from presidio_anonymizer import AnonymizerEngine

text = "Call Maria Lopez on 212-555-0199 about her claim."
results = AnalyzerEngine().analyze(text=text, language="en")
print(AnonymizerEngine().anonymize(text=text, analyzer_results=results).text)
# e.g. "Call <PERSON> on <PHONE_NUMBER> about her claim."
```

### 4. Extend

You add custom recognizers for your own identifiers, such as policy numbers, using a pattern recognizer with a regex, a score and context words. You can also swap in a different NER model for better accuracy in your language or domain.

### 5. Deploy

Presidio runs in-process as a library, or as separate analyzer and anonymizer services with a REST interface. In LLM pipelines it is often placed in a gateway or middleware layer that every request passes through.

## Key concepts and terms

| Term | Meaning |
|---|---|
| PII | Personally identifiable information |
| Entity type | Category of PII, such as PERSON or EMAIL_ADDRESS |
| Recognizer | A detector for one or more entity types |
| NER | Named-entity recognition, a model that finds names, places and organisations |
| Pattern recognizer | A recognizer based on regular expressions |
| Context words | Nearby words that raise detection confidence |
| Score threshold | Minimum confidence for a finding to count |
| Operator | The anonymisation action applied to an entity |
| Pseudonymisation | Replacing identifiers with consistent substitutes |
| Deanonymisation | Restoring original values from reversible operators |
| Allow list | Values that should never be flagged |

## A worked example

This is an illustrative scenario.

A clinic uses a hosted LLM to summarise patient messages for staff. Policy says names, phone numbers, email addresses and NHS-style patient numbers must not leave the clinic's systems.

1. They add a custom pattern recognizer for their 10-digit patient number format with context words "patient", "NHS" and "number".
2. Each message is analysed before the LLM call. Findings are encrypted with a key held in the clinic, producing tokens that the model sees in place of the values.
3. The model returns a summary that refers to the tokens. The application decrypts them before showing the summary to staff.
4. They test on 1,000 historical messages labelled by hand. The analyzer catches 97% of phone numbers and emails, but only 88% of names, missing mostly unusual spellings and lower-case names.
5. They switch to a larger NER model and add a deny list of common local surnames, raising name recall to 94%, and keep a human review step for messages that will be stored.

The team documents the remaining miss rate rather than claiming full anonymisation.

## Strengths and limitations

**Strengths:**

- Covers many common PII types out of the box.
- Combines rules, checksums, context and NER models.
- Flexible operators, including reversible encryption.
- Easy to extend with custom recognizers and models.
- Text, image and structured data support; MIT licence.

**Limitations:**

- Detection is probabilistic and will miss some PII and flag some safe text.
- Accuracy depends heavily on the NER model, language and domain.
- Free-text identifiers, such as descriptions of a person, are hard to catch.
- Anonymisation of text does not by itself guarantee legal anonymity.
- Larger NER and language models add latency and resource needs.

## How it compares with alternatives

| Option | Approach | Strength | Consider it when |
|---|---|---|---|
| Presidio | Open-source detection and anonymisation toolkit | Flexible, extensible, self-hosted | You need control over PII handling in code |
| [Guardrails AI](/tools/guardrails-ai) | Validators around LLM calls | Many checks in one guard | PII is one check among several |
| [NeMo Guardrails](/tools/nemo-guardrails) | Programmable rails | Conversation control with PII masking rails | You already use rails for dialogue |
| [Protegrity](/tools/protegrity) | Commercial data protection platform | Enterprise tokenisation and policy | You need organisation-wide protection |
| [Format-preserving encryption](/tools/format-preserving-encryption) | Cryptographic technique | Keeps data shape for downstream systems | You need reversible protection of known fields |

## Practical guidance and best practices

1. Decide which entity types matter for your use case and data rules, then enable only those.
2. Build a labelled test set from your own data and measure precision and recall per entity type.
3. Add custom recognizers for organisation-specific identifiers.
4. Use context words to cut false positives on bare numbers.
5. Choose operators deliberately: encryption when you must restore values, hashing when you need linkage, replacement for readability.
6. Keep encryption keys outside the application and rotate them.
7. Apply Presidio to logs and traces as well as prompts.
8. Combine automated detection with access controls and, where needed, human review.

## Common mistakes

- Assuming default settings catch all PII in every language and domain.
- Using a small NER model in production without measuring recall.
- Masking prompts but storing raw text in logs.
- Treating pseudonymised data as fully anonymous.
- Forgetting allow lists, so harmless public numbers are flagged constantly.

## Frequently asked questions

### What kinds of PII can Presidio detect?

Out of the box it detects many common types, such as names, locations, dates, phone numbers, email addresses, credit card numbers, IP addresses and several country-specific identifiers. You can add your own types with custom recognizers.

### Does Presidio work in languages other than English?

Yes, if you configure an NLP model for the language and recognizers that support it. Some built-in recognizers are language-specific, so test carefully.

### Can anonymisation be reversed?

Only for reversible operators. Encrypted values can be restored with the key using the deanonymizer. Replaced, redacted or hashed values cannot be restored from the output alone.

### Is Presidio enough for GDPR compliance?

No tool alone ensures compliance. Presidio helps reduce exposure of personal data, but detection is imperfect and legal anonymity depends on context. See [GDPR](/tools/gdpr) for the regulation and seek legal advice for specific cases.

### How is Presidio used with LLMs?

It typically masks or encrypts PII in prompts before they reach a model, removes PII from model outputs and logs, and can restore encrypted values in the final response. Guardrail frameworks can call it as one of their checks.

### Can it redact images?

Yes. The image redactor uses OCR to read text in images, runs the analyzer and draws boxes over detected PII. It also supports DICOM medical images.

## Glossary

- Anonymisation: removing information so a person can no longer be identified.
- Redaction: removing or blacking out sensitive content.
- OCR: optical character recognition, reading text from images.
- Luhn checksum: a simple check digit used in card numbers.
- spaCy: an open-source NLP library used by default for NER.
- DICOM: a standard format for medical images.
- Recall: share of real PII items that were detected.
- Precision: share of detections that were really PII.

## Summary

Microsoft Presidio is an open-source toolkit that detects PII with a mix of patterns, context and NER models, and then anonymises it with configurable operators, including reversible encryption. It extends to images and structured data and is widely used to keep personal data out of LLM prompts, outputs and logs. Measure its accuracy on your own data, add custom recognizers, choose operators deliberately and combine it with other safeguards, since no automated tool catches everything. See [KVKK](/tools/kvkk) for another data-protection regime. This page is general information, not legal advice.
