Open-source · MPL-2.0 · v1.6.0

PII masking at Rust speed.
Air-gapped. GDPR-ready.

A native Polars plugin that masks sensitive data inside your pipeline — zero rows leave your infrastructure, zero Python overhead per row.

View on GitHub →
import polars as pl
import maskops
 
# load 1 million customer records
df = pl.read_csv("customers.csv")
 
# mask PII — stays in your pipeline, zero network calls
masked = df.with_columns(
    maskops.mask_pii("rut"),
    maskops.mask_pii("email"),
    maskops.mask_pii("credit_card"),
)
 
# 12.345.678-9 → **.***.***.***-*
# user@acme.com → u***@a***.com
# 4532 0151 ... → **** **** **** ****
 
✓ 1,000,000 rows masked in 2.9s
4,000×
faster than Presidio
3s
for 1 million rows
100%
air-gapped
GDPR
Art. 4(5) compliant

Everything your data pipeline needs.
Nothing it doesn't.

Built for engineers who can't afford cloud vendors in their data path — or simply don't want them there.

🔒

Air-Gapped by Design

No network calls, ever. Runs offline, in CI, behind firewalls, inside VPCs. Your data never touches an external server — by architecture, not by policy.

🔑

Format-Preserving Encryption

FPE mode (FF3-1 AES-256) produces reversible pseudonymization under GDPR Art. 4(5). Same format, different value, decryptable only with your key — which MaskOps never sees.

🌎

LATAM + EU Coverage

RUT (Chile), CPF (Brazil), CURP (Mexico), IBAN, VAT, EU national IDs, email, phone, IP, credit cards. Built for the regulatory landscape of today's data-driven business.

Native Polars Plugin

Compiles to a native .so that Polars loads as an expression plugin. Zero Python overhead per row. Parallelism via Rayon, automatic.

🔍

Detection + Masking

contains_pii tells you if a column has PII before you mask it. Useful for audits, schema validation, and compliance checks in existing pipelines.

📋

Audit-Ready

Each pattern declares its regulation, compliance category, and validation logic. Suitable for CMF NCG 311, ISO 27001, and SOC 2 auditor documentation.

Reversible pseudonymization. Your key, your data.

  • The FPE key never leaves your infrastructure — MaskOps never sees it
  • Masked values keep the original format: a RUT stays a valid-looking RUT
  • Produce a real record in 10 seconds for a regulator audit
  • GDPR Art. 4(5) compliant pseudonymization — lighter regulatory burden than raw PII
fpe_example.pyPython
import polars as pl
import maskops

# 32-byte key + 7-byte tweak — stays with you
key   = pl.lit(bytes.fromhex("a1b2c3..."))
tweak = pl.lit(b"season1")

df = pl.read_parquet("transactions.parquet")

# pseudonymize — format preserved, reversible
masked = df.with_columns(
    maskops.mask_pii_fpe("rut",   key, tweak),
    maskops.mask_pii_fpe("phone", key, tweak),
)

# 12.345.678-9 → 87.162.043-5  (reversible)
# +56 9 8765 4321 → +56 9 2341 8907

What GDPR Art. 4(5) actually means for your team

Pseudonymized data — where re-identification requires a separately-held key — still falls under GDPR, but with significantly reduced risk and lighter compliance burden. Under Art. 32, pseudonymization is an explicitly recommended security measure. MaskOps FPE mode is a direct technical implementation of that requirement. The key stays with you. The regulator is satisfied. Your analytics team keeps working.

On the cryptography: FF3-1 is proposed for deprecation in NIST's draft SP 800-38G Rev.1. We document the status, our mitigations, and the FF1 migration path openly — read the security note →

Built for the laws your clients actually face.

PII identifiers matched to the regulation that makes them sensitive.

🇪🇺 European Union GDPR

IBAN — bank identifiers
VAT numbers
NIN (UK), Personalausweis (DE)
NIR (FR), Codice Fiscale (IT)
PESEL (PL), BSN (NL), personnummer (SE)
Email, phone, IP address
Credit cards

🌎 Latin America

🇨🇱RUT (Chile) Ley 19.628 / 21.719
🇧🇷CPF (Brazil) LGPD
🇲🇽CURP (Mexico) LFPDPPP
🇦🇷DNI (Argentina) Ley 25.326
🇨🇴CC / NIT (Colombia) Ley 1581
🇪🇨Cédula (Ecuador) LOPDP
🇵🇪DNI (Peru) Ley 29733
🇺🇾Cédula (Uruguay) Ley 18.331

Simple, transparent pricing.

Start with a free 3-week pilot. Convert to a retainer when you're ready. No procurement committees, no annual lock-in.

Launch
USD200
/ month
First 10 clients · rate locked forever
  • Enterprise license (CLI + policy engine)
  • Pattern updates within 2 weeks of law changes
  • Monthly regulatory monitoring email
  • Priority support — 24h response
  • Version upgrade compatibility
  • Auditor-ready documentation (CMF, SOC 2, ISO 27001)
  • Privacy policy alignment review
  • GDPR layer for multinational data
Get in touch →

Available to the first 10 clients only.
Your rate never increases — ever.

Dual-Jurisdiction
USD700
/ month
Multinationals & GDPR subsidiaries
  • Everything in Standard
  • GDPR layer — EU pattern set configured (IBAN, VAT, EU national IDs)
  • Cross-jurisdiction compliance mapping (Chile + EU)
  • Auditor documentation for EU DPA & Chilean CPDP
  • Privacy policy alignment for dual-jurisdiction processing
  • Dedicated support for auditor & legal team questions
Get in touch →
Free pilot

Not sure yet? Start with a free 3-week integration. MaskOps integrated into one Polars pipeline, masking rules configured for your PII types, pytest coverage included, and a one-page compliance summary for your legal team — at no cost. All we ask: a short debrief call and a LinkedIn testimonial if it works.

Up and running in 60 seconds.

  1. 1
    Install from PyPIRequires Python 3.10+, Polars 0.20+
    pip install maskops
  2. 2
    Import and maskNo configuration needed for asterisk masking
    import maskops
  3. 3
    For FPE modeGenerate a 32-byte key and 7-byte tweak — store them separately from your data
  4. 4
    Enterprise / compliance retainerNeed CMF NCG 311, ISO 27001, or GDPR auditor docs? Reach out directly.
quick_start.pyPython
import polars as pl
import maskops

df = pl.DataFrame({
    "rut":   ["12.345.678-9", "9.876.543-2"],
    "email": ["user@company.cl", "admin@corp.io"],
    "phone": ["+56987654321",  "+5621234567"],
})

masked = df.with_columns(
    maskops.mask_pii("rut"),
    maskops.mask_pii("email"),
    maskops.mask_pii("phone"),
)

Let's talk.

Book a 15-minute call to discuss a free pilot. No procurement process, no deck.