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.deanonymizeris a streaming-awareRunnable; a placeholder split across two streamed chunks is stitched back before the caller sees it. (Presidio'sRunnableLambda(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)
| 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)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| 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 logRelease 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 logSecurity 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.
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 logA 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.