pii-eraser
Find personal data and secrets in text and code. Replace them with stable placeholders. Do it locally, before the text goes to a model, a log or a vendor.
Contact Jane Doe <jane.doe@example.org>, key AKIA… → Contact [NAME_1] <[EMAIL_1]>, key [SECRET_1]
- Local. Regex rules and an optional NER model run on your machine. No network.
- Stable. A session keeps one placeholder table across many texts:
Jane Doeis[NAME_1]in the diff, in every file an agent reads afterwards, and in the next file, even where no rule fires again. - Code-aware. The code profile drops rules that misfire on source (dates in changelogs, numbers that look like phones) and checks card numbers (Luhn) and IBANs (mod-97). Line counts never change, so line numbers in a review still hold.
- Reversible for the owner.
session.restore(text)puts the originals back into a model's answer, on your side.
Install
pip install pii-eraser # regex rules only, no dependencies
pip install 'pii-eraser[gliner]' # + GLiNER NER for names and organisations (~400 MB model)
Use
from pii_eraser import Eraser
eraser = Eraser.for_prose() # documents, emails, MR descriptions
result = eraser.erase("Name: Jane Doe, jane.doe@example.org")
result.text # 'Name: [NAME_1], [EMAIL_1]'
result.mapping # {'[NAME_1]': 'Jane Doe', '[EMAIL_1]': 'jane.doe@example.org'}
session = Eraser.for_code().session() # many texts, one table
session.erase(diff_text)
session.erase(file_the_agent_read)
answer = session.restore(model_answer)
With NER:
from pii_eraser.detectors.gliner import GlinerDetector
Eraser.for_prose(GlinerDetector()) # NER hits are replaced
Eraser.for_code(GlinerDetector()) # NER hits are only reported in result.signals
On source code an NER model tags variable names and authors as people. In the code profile its hits are signals for a human, not replacements.
CLI
pii-eraser contract.txt > contract.clean.txt
git diff origin/main | pii-eraser --profile code --report --fail-on-secret > /dev/null
The report on stderr lists kind, line and rule, never the original value, so it
is safe for CI logs. --fail-on-secret exits 1 when a secret is found.
Diff lines are read as they come: added, removed and context lines are all
checked, since a removed secret still sits in history.
What it finds
| Kind | Examples |
|---|---|
SECRET |
private key blocks, AWS / GitHub / GitLab / Slack / Anthropic / OpenAI / Google / Stripe keys, JWTs, passwords in URLs, password = "…" / API_KEY=… assignments, long random quoted strings |
EMAIL, PHONE |
emails; international, US, Swiss, German phone formats |
NAME |
labelled names, titles, salutations, signature blocks, contract parties; with NER: any person or organisation |
ADDRESS |
US street / city / state / ZIP, UK postcodes, German streets, labelled addresses |
FINANCIAL |
payment cards (Luhn), IBAN (mod-97), account, routing, tax ids |
SSN, NATIONAL_ID, DOB, MRN, HEALTH_PLAN_ID |
US SSN, Swiss AHV, Spanish NIE/DNI, UK NI, passports, licences, dates of birth, medical record and insurance numbers (EN/DE) |
References to secrets are left alone: ${DB_PASSWORD}, <your-token>,
os.environ['SECRET'], changeme.
Limits
Detection is heuristic. Rules miss formats they don't know; NER misses rare names and catches some non-names. Treat the output as reduced exposure, not as anonymisation in the legal sense, and keep a secret scanner such as gitleaks in your pipeline: a leaked key must be rotated, not just masked.
Origin
The personal-data rules and NER filters come from the scrubber of 37lab's contract analyzer, tuned on real contracts, medical notes and business email. The secret rules, sessions and the code profile were added for agentic code review in semantic-diff.
License
MIT — 37lab. The default NER model
urchade/gliner_medium-v2.1 is Apache-2.0.
Metadata
Release files for pii-eraser 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pii_eraser-0.1.1.tar.gz | 20.5 kB | Without provenance | Details for pii_eraser-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pii_eraser-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for pii_eraser-0.1.1-py3-none-any.whl |
Total release size: 42.6 kB
Release files / pii_eraser-0.1.1.tar.gz
| Download URL | pii_eraser-0.1.1.tar.gz |
|---|---|
| Size | 20.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
14b460d3175d0ae875c3c271c9e72b9be591564f02daec594b34a2cfa020c5eb
|
|
BLAKE2b-256 checksum How to use checksums |
4c0491cc528513f83ba57b4637b0141d010f87e4f1c925c2bed17c8c04f57db1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.13
|
Release files / pii_eraser-0.1.1-py3-none-any.whl
| Download URL | pii_eraser-0.1.1-py3-none-any.whl |
|---|---|
| Size | 22.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d35e8d4d904c292e7faa8d1e44037cbebc9373178337b2e709d3260d9bbd8882
|
|
BLAKE2b-256 checksum How to use checksums |
71d7c65050b84ad770160f9264102e619a506d3bb933470908346b6945c9bcff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.13
|
Security for pii-eraser 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.