Skip to main content

maskflow-langchain

MaskFlow for LangChain: a reversible PII anonymizer / deanonymizer pair that drops in for langchain-experimental's Presidio anonymizer, plus a leak-guard callback.

It runs MaskFlow's detection engine, so alongside the usual PII (email, phone, card numbers, ...) it covers the Indian identifiers most tools miss: Aadhaar, PAN, GSTIN, UPI VPA, IFSC, ABHA, Indian mobile / PIN code / voter ID / passport / driving licence / vehicle registration, and Indian names and addresses.

  • Drop-in. Same method names and mapping shapes as PresidioReversibleAnonymizer, so migrating a chain is one import line.
  • Streaming. anonymizer.deanonymizer is a streaming-aware Runnable; a placeholder split across two streamed chunks is stitched back before the caller sees it. (Presidio's RunnableLambda(deanonymize) only fires on the final string.)
  • Leak guard. An optional callback that fails a call closed if a prompt still contains PII.
  • MIT, no gates, no telemetry.

Install

pip install maskflow-langchain
pip install "maskflow-langchain[yaml]"   # if you save/load mappings as .yaml

langchain-core is a real dependency (>=0.3,<2). The first detection run downloads a small spaCy model for the name/address recognizers; pass patterns_only=True to skip it.

Migrating from the Presidio anonymizer

# from langchain_experimental.data_anonymizer import PresidioReversibleAnonymizer
from maskflow_langchain import MaskflowReversibleAnonymizer as PresidioReversibleAnonymizer

Everything a chain touches keeps working: .anonymize(text, language=None, allow_list=None), .deanonymize(text, strategy=exact_matching_strategy), .reset_deanonymizer_mapping(), .deanonymizer_mapping, .anonymizer_mapping, .save_deanonymizer_mapping(path), .load_deanonymizer_mapping(path).

Two methods differ, because Presidio recognizer and operator objects have no MaskFlow equivalent:

Presidio maskflow-langchain
add_recognizer(recognizer_obj) add_recognizer(entity_type=..., regex=..., base_confidence=0.6)
add_operators({e: OperatorConfig(...)}) add_operators({e: "replace"|"redact"|"mask"|"hash"|"surrogate"})

allow_list is passed to the constructor on the reversible anonymizer (the session is built once); a differing per-call allow_list raises.

Use it in a chain

from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from maskflow_langchain import MaskflowReversibleAnonymizer

anonymizer = MaskflowReversibleAnonymizer()
prompt = ChatPromptTemplate.from_template("Answer: {question}")

chain = (
    {"question": lambda x: anonymizer.anonymize(x["question"])}
    | prompt
    | llm
    | StrOutputParser()
    | anonymizer.deanonymizer  # streaming-aware
)

chain.invoke({"question": "Is PAN ABCPE1234F valid for a salaried filer?"})
# the LLM sees "<PAN_1>"; you get "ABCPE1234F" back
for piece in chain.stream({"question": "Confirm receipt of PAN ABCPE1234F"}):
    print(piece, end="")  # deanonymized incrementally

Leak-guard callback

from maskflow_langchain import MaskflowLeakGuardCallback

guard = MaskflowLeakGuardCallback(raise_on_prompt_pii=True)
chain.invoke(x, config={"callbacks": [guard]})
# raises MaskflowPIILeakError if a prompt reaching the LLM still has PII

guard.summary()  # {"prompt": {"PAN": 0}, "completion": {...}} -- counts only, never values

Callbacks cannot rewrite prompts, so this does not mask; it audits (entity types and counts, never values) and, with raise_on_prompt_pii=True, aborts a call that would leak.

PII safety

No original value is written to logs, repr, callback state, or a saved mapping's structure beyond what you explicitly persist with save_deanonymizer_mapping (which, like Presidio's, contains the real values -- treat that file as sensitive).

See docs/langchain.md in the MaskFlow repo for design notes.

Metadata

Release files for maskflow-langchain 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for maskflow-langchain 0.1.1
File Size Uploaded Provenance Actions
maskflow_langchain-0.1.1.tar.gz 14.8 kB With provenance Details for maskflow_langchain-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for maskflow-langchain 0.1.1
File Interpreter ABI Platform Actions
maskflow_langchain-0.1.1-py3-none-any.whl Python 3 none any Details for maskflow_langchain-0.1.1-py3-none-any.whl

Total release size: 28.4 kB

Release files / maskflow_langchain-0.1.1.tar.gz

Download URL maskflow_langchain-0.1.1.tar.gz
Size 14.8 kB
Tags Source
SHA-256 checksum
How to use checksums
52b5c3311eda83920462acad59203070dcc29cf56589f93ab2a54c35d443f08d
BLAKE2b-256 checksum
How to use checksums
6212ec0ff87340c1b5ae29cc7cc376d9129b5e2fe7acd279c4343febe5163399
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

Release files / maskflow_langchain-0.1.1-py3-none-any.whl

Download URL maskflow_langchain-0.1.1-py3-none-any.whl
Size 13.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
01985f5f3996887f9c2d520f56ffb3915d616c4fcc40db560afae1a19c25cd07
BLAKE2b-256 checksum
How to use checksums
5d34623e830e7244a7ba5e1b3318400eee6e6db5b8628f4f9892557b79f53218
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

Security for maskflow-langchain 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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for maskflow_langchain-0.1.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

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.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page