OpenRung
A free, privacy-first relay network that helps you reach the open internet. Open source and nonprofit-run.
Open-source PII detection and redaction for Python and Node.js. 31 European countries, 29 entity types, checksum validation, ~1.6ms per page (Node). Apache 2.0.
SecurityPython · TypeScriptGitHub @euredactAvailability needs another checkOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
European PII redaction SDK — rule engine + cloud tier. Python & TypeScript.
Translation pending
Loading the full README.
Read the full README ↗European PII detection and redaction SDK -- available for Python and Node.js.
euRedact Core is the open-source SDK: it runs on your machine and detects and redacts personally identifiable information across 31 European countries using a two-pass rule engine: liberal pattern matching followed by checksum validation, context-aware suppression, and priority-based deduplication. Zero required dependencies in both languages.
pip install euredact
import euredact
result = euredact.redact("Mijn BSN is 111222333 en IBAN NL91ABNA0417164300.")
print(result.redacted_text)
# "Mijn BSN is [NATIONAL_ID] en IBAN [BANK_ACCOUNT]."
npm install euredact
import { redact } from "euredact";
const result = redact("Mijn BSN is 123456782 en email [email protected]", {
countries: ["NL"],
});
console.log(result.redactedText);
// "Mijn BSN is [NATIONAL_ID] en email [EMAIL]"
mode="cloud" adds a fine-tuned model for the categories that have no shape to match on — person names, organisations, job titles, diagnoses+CC dialling codes, VAT prefixes, BIC, email ccTLDs — so an ambiguous value resolves without the caller naming a country. countries never gates what is looked for; it scores and flagstokenize=True swaps values for EMAIL_K7Q2-style tokens and restore() puts them back — for prompts that go to an LLM and come back with the tokens in them| Region | Countries |
|---|---|
| Western Europe | AT, BE, CH, DE, FR, LU, NL |
| Southern Europe | CY, EL, ES, IT, MT, PT |
| Northern Europe | DK, EE, FI, IS, LT, LV, NO, SE |
| Eastern Europe | BG, CZ, HR, HU, PL, RO, SI, SK |
| British Isles | IE, UK |
EntityType has 41 distinct values. The rule engine emits the 29 that have
a shape to match on:
NATIONAL_ID BANK_ACCOUNT PHONE EMAIL
CREDIT_CARD VAT TAX_ID SSN
PASSPORT DRIVERS_LICENSE LICENSE_PLATE POSTAL_CODE
BIC VIN IMEI SECRET
IP_ADDRESS IPV6_ADDRESS MAC_ADDRESS UUID
GPS_COORDINATES SOCIAL_HANDLE DOB DATE_OF_DEATH
HEALTH_INSURANCE HEALTHCARE_PROVIDER CHAMBER_OF_COMMERCE
RESIDENCE_PERMIT INTERNAL_ID
11 are the cloud tier's. The rule engine never emits them — there is no shape to match on, which is precisely why the model exists:
PERSON_NAME ADDRESS ORGANISATION_NAME JOB_TITLE
MEDICAL_CONDITION SENSITIVE_ATTRIBUTE BIOMETRIC_REF FINANCIAL_AMOUNT
QUASI_IDENTIFIER URL LOCATION
The last is OTHER: the cloud client's fallback for a label the service
returns and the SDK does not know. Neither layer detects anything as OTHER.
Three names are legacy aliases kept so existing code keeps working:
IBAN → BANK_ACCOUNT, NAME → PERSON_NAME and CREDENTIAL → SECRET
(the cloud model's label for prose passwords and connection-string secrets).
The alias resolves to the canonical member, so the placeholder written into
redacted text is [BANK_ACCOUNT], [PERSON_NAME] and [SECRET]. LEGACY_TYPE_ALIASES publishes the full
mapping, which also recognises the string forms STREET_ADDRESS → ADDRESS
and NATIONALITY_ETHNICITY → SENSITIVE_ATTRIBUTE.
Each detection carries a confidence of "high" (a pattern matched and its
checksum passed), "medium" (the type comes from a label touching the span,
because no pattern of that type claimed it) or "low" (a pattern matched, its
checksum failed, and the document labels the span as that very type). Every
detection is masked regardless; filter on confidence == "high" if you need
only checksum-backed types.
Status: private alpha. The cloud tier is in closed testing — it is not in public beta and is not generally available. Keys are issued to alpha participants only, and the request/response surface may still change between releases. The rules engine below is unaffected and is the supported path:
mode="rules"is the default and carries no alpha caveat.
This is the beginning of the README. Read the rest at the original. Read the full README ↗