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.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file maskflow_langchain-0.1.1.tar.gz.
File metadata
- Download URL: maskflow_langchain-0.1.1.tar.gz
- Upload date:
- Size: 14.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52b5c3311eda83920462acad59203070dcc29cf56589f93ab2a54c35d443f08d
|
|
| MD5 |
505aed0accb7b8ea08eaf60f170894c2
|
|
| BLAKE2b-256 |
6212ec0ff87340c1b5ae29cc7cc376d9129b5e2fe7acd279c4343febe5163399
|
Provenance
The following attestation bundles were made for maskflow_langchain-0.1.1.tar.gz:
Publisher:
release-langchain.yml on maskflow/maskflow
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
maskflow_langchain-0.1.1.tar.gz -
Subject digest:
52b5c3311eda83920462acad59203070dcc29cf56589f93ab2a54c35d443f08d - Sigstore transparency entry: 2804332298
- Sigstore integration time:
-
Permalink:
maskflow/maskflow@3000dcbfe722e734b2b74db8368836ab320675da -
Branch / Tag:
refs/tags/langchain-v0.1.1 - Owner: https://github.com/maskflow
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-langchain.yml@3000dcbfe722e734b2b74db8368836ab320675da -
Trigger Event:
push
-
Statement type:
File details
Details for the file maskflow_langchain-0.1.1-py3-none-any.whl.
File metadata
- Download URL: maskflow_langchain-0.1.1-py3-none-any.whl
- Upload date:
- Size: 13.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
01985f5f3996887f9c2d520f56ffb3915d616c4fcc40db560afae1a19c25cd07
|
|
| MD5 |
8fba3e979aa907b98178de833ef6bb8e
|
|
| BLAKE2b-256 |
5d34623e830e7244a7ba5e1b3318400eee6e6db5b8628f4f9892557b79f53218
|
Provenance
The following attestation bundles were made for maskflow_langchain-0.1.1-py3-none-any.whl:
Publisher:
release-langchain.yml on maskflow/maskflow
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
maskflow_langchain-0.1.1-py3-none-any.whl -
Subject digest:
01985f5f3996887f9c2d520f56ffb3915d616c4fcc40db560afae1a19c25cd07 - Sigstore transparency entry: 2804332388
- Sigstore integration time:
-
Permalink:
maskflow/maskflow@3000dcbfe722e734b2b74db8368836ab320675da -
Branch / Tag:
refs/tags/langchain-v0.1.1 - Owner: https://github.com/maskflow
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-langchain.yml@3000dcbfe722e734b2b74db8368836ab320675da -
Trigger Event:
push
-
Statement type: