Open-source · MPL-2.0 · v2.0.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
340×
faster than Presidio
1.7s
for 1 million rows
100%
air-gapped
GDPR
Art. 4(5) compliant

Like-for-like structured-PII masking (email, phone, IP, IBAN, card) vs Presidio on 1M rows. Methodology & full numbers →

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 paid pilot on your own data, with the fee credited in full when you convert. No procurement committees, no annual lock-in.

One Ley 21.719 fine can reach about USD 1.5M. One Brazilian finance-sector breach averages R$8.9M. A retainer is a rounding error against either.

MaskOps itself is 100% open source under MPL-2.0 — every pattern, the CLI, and the policy engine. Paid plans are support and compliance services, not a different or closed version of the software.

Launch
USD200
/ month
First 10 clients · rate locked forever
  • Commercial support for the full open-source 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 →
Enterprise support

Request pricing. Hands-on help deploying MaskOps air-gapped and on-prem, guaranteed-response support, compliance reporting, and dedicated integration support for fintechs embedding it into their pipelines. Priced to your deployment and anchored to the exposure it removes, not a per-seat number.

Request pricing →
Paid pilot

Start on your own data, not a demo. A fixed 60 to 90 day paid pilot: MaskOps integrated into one Polars pipeline, masking rules configured for your PII, and one success test agreed up front (mask 1M rows in under 3 seconds, pass an auditor manifest review). The fee is credited in full when you convert, and refunded if the test fails. Your only risk is time.

Up and running in 60 seconds.

  1. 1
    Install from PyPIRequires Python 3.9+, Polars 0.46+
    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 pilot. No procurement process, no deck.