<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michal Vich</title>
    <description>The latest articles on DEV Community by Michal Vich (@mnagas).</description>
    <link>https://dev.to/mnagas</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3804616%2Fa6fcbe68-3b20-4da1-8dc7-b4e1bd61897a.jpg</url>
      <title>DEV Community: Michal Vich</title>
      <link>https://dev.to/mnagas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mnagas"/>
    <language>en</language>
    <item>
      <title>Stop Leaking Customer Data to LLMs — A 60-Second Fix</title>
      <dc:creator>Michal Vich</dc:creator>
      <pubDate>Tue, 03 Mar 2026 21:23:32 +0000</pubDate>
      <link>https://dev.to/mnagas/stop-leaking-customer-data-to-llms-a-60-second-fix-3k6l</link>
      <guid>https://dev.to/mnagas/stop-leaking-customer-data-to-llms-a-60-second-fix-3k6l</guid>
      <description>&lt;p&gt;Every time we call OpenAI, Anthropic, or any LLM API, the input gets logged on their servers. If that input contains a customer's name, email, SSN, or credit card number — congratulations, we just sent PII to a third party.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers Nobody Wants to See
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GDPR fines in 2024: &lt;strong&gt;€2.1 billion&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Average data breach lawsuit settlement: &lt;strong&gt;$3.8 million&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;HIPAA violation penalty range: &lt;strong&gt;$100 to $50,000 per record&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And it's not just fines. One customer complaint to a data protection authority triggers an investigation. If they find we've been piping raw personal data to OpenAI's API — with no safeguards, no data processing agreement, no anonymization — that's not a good day.&lt;/p&gt;

&lt;p&gt;Most AI apps handle exactly this kind of data: support tickets, medical intake, financial queries, HR documents. The LLM needs context to be useful, but that context is full of PII.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Simple Fix
&lt;/h2&gt;

&lt;p&gt;Replace PII with tokens before it hits the model. Restore the originals in the output. The model never sees real data, the response is still complete.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input:  "John Doe (john@acme.com) needs a refund"
    ↓ tokenize
Safe:   "&amp;lt;Person_1&amp;gt; (&amp;lt;Email Address_1&amp;gt;) needs a refund"
    ↓ LLM processes it
Output: "I've processed &amp;lt;Person_1&amp;gt;'s refund request"
    ↓ detokenize
Final:  "I've processed John Doe's refund request"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Three steps. The model works with placeholders, the output reads naturally, and customer data stays on our side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation (60 Seconds)
&lt;/h2&gt;

&lt;p&gt;Install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;blindfold-sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run — no API key needed, works offline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;blindfold&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Blindfold&lt;/span&gt;

&lt;span class="n"&gt;bf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Blindfold&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Contact us at sarah@example.com or 555-867-5309. SSN: 123-45-6789&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Detect PII
&lt;/span&gt;&lt;span class="n"&gt;detected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;detect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;detected&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;detected_entities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; (score: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Email Address: 'sarah@example.com' (score: 0.95)
# Phone Number: '555-867-5309' (score: 0.90)
# Social Security Number: '123-45-6789' (score: 1.00)
&lt;/span&gt;
&lt;span class="c1"&gt;# Tokenize
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tokenize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# "Contact us at &amp;lt;Email Address_1&amp;gt; or &amp;lt;Phone Number_1&amp;gt;. SSN: &amp;lt;Social Security Number_1&amp;gt;"
&lt;/span&gt;
&lt;span class="c1"&gt;# Detokenize — restore originals
&lt;/span&gt;&lt;span class="n"&gt;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;detokenize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# "Contact us at sarah@example.com or 555-867-5309. SSN: 123-45-6789"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's local mode. No API key, no network calls, nothing leaves the machine. 86 regex detectors, 80+ entity types, 30+ countries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plug It Into Any LLM
&lt;/h2&gt;

&lt;p&gt;Here's the full pattern with OpenAI. Set your API keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;BLINDFOLD_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-blindfold-api-key"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-openai-api-key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;blindfold&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Blindfold&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;bf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Blindfold&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;user_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Write a follow-up email to John Doe at john@example.com &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;about his refund for order #1234.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Tokenize
&lt;/span&gt;&lt;span class="n"&gt;tokenized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tokenize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;basic&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# "&amp;lt;Person_1&amp;gt; at &amp;lt;Email Address_1&amp;gt;..." — no real data
&lt;/span&gt;
&lt;span class="c1"&gt;# 2. Send safe text to LLM
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;system&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a customer support assistant.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tokenized&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;llm_output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Restore originals
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;detokenize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm_output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tokenized&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# The email now reads "John Doe" and "john@example.com" — not tokens
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Swap &lt;code&gt;openai&lt;/code&gt; for &lt;code&gt;anthropic&lt;/code&gt;, &lt;code&gt;mistralai&lt;/code&gt;, &lt;code&gt;cohere&lt;/code&gt;, or a local model on Ollama. Blindfold doesn't care what's in the middle.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Gets Detected
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Local mode (regex, no API key):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Email addresses&lt;/li&gt;
&lt;li&gt;Phone numbers (international formats)&lt;/li&gt;
&lt;li&gt;Social Security Numbers&lt;/li&gt;
&lt;li&gt;Credit card numbers (with Luhn validation)&lt;/li&gt;
&lt;li&gt;IBANs (30+ countries)&lt;/li&gt;
&lt;li&gt;IP addresses (v4 and v6)&lt;/li&gt;
&lt;li&gt;Dates of birth&lt;/li&gt;
&lt;li&gt;Passport numbers, driver's licenses&lt;/li&gt;
&lt;li&gt;Tax IDs, VAT numbers&lt;/li&gt;
&lt;li&gt;URLs, cryptocurrency addresses&lt;/li&gt;
&lt;li&gt;80+ entity types total&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cloud API (AI + regex):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Everything above, plus:&lt;/li&gt;
&lt;li&gt;Person names (any language)&lt;/li&gt;
&lt;li&gt;Company names&lt;/li&gt;
&lt;li&gt;Physical addresses&lt;/li&gt;
&lt;li&gt;Medical terms and conditions&lt;/li&gt;
&lt;li&gt;Context-dependent entities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Local mode handles structured patterns. The cloud API adds AI-based detection for things regex can't catch — like knowing "Springfield" is an address in one sentence and a company name in another.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not Just Redaction
&lt;/h2&gt;

&lt;p&gt;Most tools only redact. Blindfold gives us six options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;tokenize&lt;/strong&gt; → &lt;code&gt;&amp;lt;Person_1&amp;gt;&lt;/code&gt; — Send to LLM, restore later. Reversible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;redact&lt;/strong&gt; → &lt;code&gt;[REDACTED]&lt;/code&gt; — Gone forever. For logs, indexes, storage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;mask&lt;/strong&gt; → &lt;code&gt;J*** D**&lt;/code&gt; — Show partial data to end users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hash&lt;/strong&gt; → &lt;code&gt;a1b2c3d4...&lt;/code&gt; — Analytics and dedup without exposing data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;synthesize&lt;/strong&gt; → &lt;code&gt;Jane Smith&lt;/code&gt; — Realistic fake data for testing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;encrypt&lt;/strong&gt; → &lt;code&gt;enc:x8f2k...&lt;/code&gt; — Reversible with a key. For compliance archives.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Redaction is fine for logs. But for LLM pipelines, we need &lt;strong&gt;tokenize&lt;/strong&gt; — the model works with placeholders, and we restore the originals after. One-way redaction breaks the workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built-In Compliance Policies
&lt;/h2&gt;

&lt;p&gt;Instead of manually listing which entity types to detect, we pick a policy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;basic&lt;/strong&gt; — Names, emails, phones, locations. General apps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gdpr_eu&lt;/strong&gt; — Adds IBANs, dates of birth, EU-specific identifiers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hipaa_us&lt;/strong&gt; — Adds SSNs, medical record numbers, health data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pci_dss&lt;/strong&gt; — Adds card numbers, CVVs, expiry dates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;strict&lt;/strong&gt; — Everything, lower confidence threshold.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One parameter. Done.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tokenize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hipaa_us&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Not Build It Yourself?
&lt;/h2&gt;

&lt;p&gt;I tried. Here's what happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We start with a regex for emails. Easy.&lt;/li&gt;
&lt;li&gt;Add phone numbers. Now we need 20+ international formats.&lt;/li&gt;
&lt;li&gt;Credit cards need Luhn validation. SSNs need range checks.&lt;/li&gt;
&lt;li&gt;IBANs are different for every country. 30+ formats.&lt;/li&gt;
&lt;li&gt;Person names? Regex can't do that. Now we need NLP.&lt;/li&gt;
&lt;li&gt;Six months later, we have a fragile pile of regexes that misses half the edge cases and we're maintaining it instead of building our product.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Blindfold ships 86 regex detectors covering 80+ entity types out of the box. The cloud API adds AI detection for names and context-dependent entities. It's tested, it's maintained, and it's not our problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Residency
&lt;/h2&gt;

&lt;p&gt;For regulated industries, where data is processed matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;region="eu"&lt;/code&gt; → Frankfurt, Germany&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;region="us"&lt;/code&gt; → Virginia, US
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;bf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Blindfold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eu&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Data stays in the region. No transatlantic transfers. GDPR auditors stop asking questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's Not Just Python
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript/TypeScript&lt;/strong&gt;: &lt;code&gt;npm install @blindfold/sdk&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Go&lt;/strong&gt;: &lt;code&gt;go get github.com/blindfold-dev/blindfold-go&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Java&lt;/strong&gt;: Maven Central &lt;code&gt;dev.blindfold:blindfold-sdk&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;.NET&lt;/strong&gt;: NuGet &lt;code&gt;Blindfold.Sdk&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLI&lt;/strong&gt;: &lt;code&gt;npm install -g @blindfold/cli&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Server&lt;/strong&gt;: &lt;code&gt;npm install @blindfold/mcp-server&lt;/code&gt; (for AI agents)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LangChain&lt;/strong&gt;: &lt;code&gt;pip install langchain-blindfold&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same API, same policies, same token format across all of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing Reality
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local mode&lt;/strong&gt;: Free. Forever. No API key. No limits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud API free tier&lt;/strong&gt;: 500K characters/month. No credit card.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paid plans&lt;/strong&gt;: Usage-based. Pay for what we use.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No $200/month minimums. No enterprise-only tiers to get basic features. Local mode alone covers most use cases — the cloud API is there when we need AI-powered name and address detection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;blindfold-sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;blindfold&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Blindfold&lt;/span&gt;
&lt;span class="n"&gt;bf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Blindfold&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tokenize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Call me at 555-0123, my SSN is 123-45-6789&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# "Call me at &amp;lt;Phone Number_1&amp;gt;, my SSN is &amp;lt;Social Security Number_1&amp;gt;"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three lines. No API key. Run it right now.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.blindfold.dev" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/blindfold-dev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://app.blindfold.dev" rel="noopener noreferrer"&gt;Dashboard&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Stop trusting LLM providers with customer data. Tokenize first.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Protect PII in LLM Pipelines with Python</title>
      <dc:creator>Michal Vich</dc:creator>
      <pubDate>Tue, 03 Mar 2026 21:02:31 +0000</pubDate>
      <link>https://dev.to/mnagas/how-to-protect-pii-in-llm-pipelines-with-python-pek</link>
      <guid>https://dev.to/mnagas/how-to-protect-pii-in-llm-pipelines-with-python-pek</guid>
      <description>&lt;p&gt;&lt;em&gt;Tokenize personal data before it reaches the model, restore it in the output.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;If we're building AI features that handle customer data — support tickets, medical intake, financial queries — we have a problem. Every prompt we send to an LLM API is logged, cached, and potentially used for training. Names, emails, SSNs, medical records: all of it lands on someone else's servers.&lt;/p&gt;

&lt;p&gt;GDPR says we can't send EU personal data to third-party processors without safeguards. HIPAA says protected health information must be de-identified. And even outside regulated industries, sending raw customer data to OpenAI or Anthropic is a liability we shouldn't accept.&lt;/p&gt;

&lt;p&gt;Here's what a naive implementation looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Every name, email, and SSN in this text hits OpenAI's servers
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Summarize this support ticket: Customer John Doe (john@acme.com) &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;called about order #4521. His SSN 123-45-6789 was used for verification.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;John Doe's name, email, and SSN are now in OpenAI's logs. We can do better.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Approach: Tokenize, Process, Detokenize
&lt;/h2&gt;

&lt;p&gt;The fix is straightforward: replace PII with deterministic tokens &lt;em&gt;before&lt;/em&gt; it reaches the model, then restore the originals in the output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"John Doe (john@acme.com)"
    ↓ tokenize
"&amp;lt;Person_1&amp;gt; (&amp;lt;Email Address_1&amp;gt;)"
    ↓ send to LLM
"I've noted &amp;lt;Person_1&amp;gt;'s issue..."
    ↓ detokenize
"I've noted John Doe's issue..."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model never sees real data. It works with placeholders that preserve sentence structure, so the output quality stays the same. When we detokenize, the final response reads naturally with all the original values restored.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blindfold.dev" rel="noopener noreferrer"&gt;Blindfold&lt;/a&gt; handles both sides of this — the PII detection and the token mapping — and it works with any LLM provider (OpenAI, Anthropic, Mistral, local models, etc.).&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;blindfold-sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all we need to start. Blindfold works locally out of the box — no API key, no account, no network calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example 1: Try It Locally (No API Key, No Network Calls)
&lt;/h2&gt;

&lt;p&gt;Let's start with something we can run right now. Without an API key, Blindfold runs entirely on our machine using regex-based detection. Nothing leaves the process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;blindfold&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Blindfold&lt;/span&gt;

&lt;span class="c1"&gt;# No API key = local mode (regex-only, runs entirely on your machine)
&lt;/span&gt;&lt;span class="n"&gt;bf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Blindfold&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Contact us at sarah@example.com or 555-867-5309. SSN: 123-45-6789&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Detect — find PII without modifying the text
&lt;/span&gt;&lt;span class="n"&gt;detected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;detect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Found &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;detected&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;entities_count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; entities:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;detected&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;detected_entities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; (score: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Found 3 entities:
#   Email Address: 'sarah@example.com' (score: 0.95)
#   Phone Number: '555-867-5309' (score: 0.90)
#   Social Security Number: '123-45-6789' (score: 1.00)
&lt;/span&gt;
&lt;span class="c1"&gt;# Tokenize — replace PII with reversible tokens
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tokenize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Tokenized: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Tokenized: Contact us at &amp;lt;Email Address_1&amp;gt; or &amp;lt;Phone Number_1&amp;gt;. SSN: &amp;lt;Social Security Number_1&amp;gt;
&lt;/span&gt;
&lt;span class="c1"&gt;# Detokenize — restore originals
&lt;/span&gt;&lt;span class="n"&gt;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;detokenize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Restored: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Restored: Contact us at sarah@example.com or 555-867-5309. SSN: 123-45-6789
&lt;/span&gt;
&lt;span class="c1"&gt;# Redact — permanently remove PII
&lt;/span&gt;&lt;span class="n"&gt;redacted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Redacted: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;redacted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Redacted: Contact us at [REDACTED] or [REDACTED]. SSN: [REDACTED]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Local mode covers 80+ pattern-based entity types (emails, phone numbers, SSNs, credit cards, IBANs, and more) across 30+ countries using 86 built-in regex detectors. It's fast, deterministic, and has zero external dependencies. For detecting names, addresses, and other context-dependent entities, we switch to the cloud API (Example 4), which adds AI-based detection on top of the regex layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example 2: Detect-Only Mode
&lt;/h2&gt;

&lt;p&gt;Sometimes we don't want to modify text — just know what PII is in it. The &lt;code&gt;detect()&lt;/code&gt; method returns every entity with its type, position, and confidence score:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;blindfold&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Blindfold&lt;/span&gt;

&lt;span class="n"&gt;bf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Blindfold&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;detect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Email john@acme.com or call 555-0123. SSN: 123-45-6789&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;strict&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;detected_entities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; (score: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Email Address: 'john@acme.com' (score: 0.95)
# Phone Number: '555-0123' (score: 0.90)
# Social Security Number: '123-45-6789' (score: 1.00)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use this to build guardrails: block messages containing PII before they reach the model, generate audit trails for compliance, or flag content for human review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going Further: Cloud API
&lt;/h2&gt;

&lt;p&gt;When we need to detect names, addresses, and other context-dependent entities — not just structured patterns — we switch to the Blindfold cloud API, which adds AI-based detection on top of the regex layer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;BLINDFOLD_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-blindfold-api-key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sign up at &lt;a href="https://blindfold.dev" rel="noopener noreferrer"&gt;blindfold.dev&lt;/a&gt; to get an API key. The free tier covers 500K characters per month.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example 3: Redact PII from Documents
&lt;/h2&gt;

&lt;p&gt;When storing or indexing text (RAG pipelines, search indexes, logs), we often want PII permanently removed rather than tokenized:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;blindfold&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Blindfold&lt;/span&gt;

&lt;span class="n"&gt;bf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Blindfold&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# uses BLINDFOLD_API_KEY env var
&lt;/span&gt;
&lt;span class="n"&gt;medical_note&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Patient Sarah Johnson (DOB 03/15/1985) was diagnosed with &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Type 2 diabetes. Contact: sarah.j@email.com, SSN 234-56-7890.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;redacted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;medical_note&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hipaa_us&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;redacted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# "Patient [REDACTED] (DOB [REDACTED]) was diagnosed with
#  Type 2 diabetes. Contact: [REDACTED], SSN [REDACTED]."
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;code&gt;redact()&lt;/code&gt;, PII is permanently removed — there's no mapping to reverse. Notice that "Sarah Johnson" is detected as a person name — this requires the cloud API's AI model; local regex mode can't detect arbitrary names. This is the right choice for indexing, logging, or any case where we want the data gone, not just hidden.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example 4: Protect Any LLM Call (Cloud API)
&lt;/h2&gt;

&lt;p&gt;The full pattern: tokenize the input (including names), send safe text to the model, detokenize the output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;openai
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-openai-api-key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;blindfold&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Blindfold&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;bf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Blindfold&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;user_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Write a follow-up email to John Doe at john@example.com &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;about his refund for order #1234.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Step 1: Tokenize — PII is replaced with tokens
&lt;/span&gt;&lt;span class="n"&gt;tokenized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tokenize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;basic&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokenized&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# "Write a follow-up email to &amp;lt;Person_1&amp;gt; at &amp;lt;Email Address_1&amp;gt;
#  about his refund for order #1234."
&lt;/span&gt;
&lt;span class="c1"&gt;# Step 2: Send safe text to the LLM
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;system&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a helpful customer support assistant.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tokenized&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;llm_output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;
&lt;span class="c1"&gt;# The model drafts an email to &amp;lt;Person_1&amp;gt; at &amp;lt;Email Address_1&amp;gt;
&lt;/span&gt;
&lt;span class="c1"&gt;# Step 3: Detokenize — restore original values
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;detokenize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm_output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tokenized&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# The model's email now reads "John Doe" and "john@example.com"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;policy&lt;/code&gt; parameter controls which entity types are detected. &lt;code&gt;"basic"&lt;/code&gt; covers names, emails, phone numbers, and locations. For regulated workloads, use &lt;code&gt;"gdpr_eu"&lt;/code&gt;, &lt;code&gt;"hipaa_us"&lt;/code&gt;, or &lt;code&gt;"pci_dss"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This pattern works with any LLM provider — swap &lt;code&gt;openai&lt;/code&gt; for &lt;code&gt;anthropic&lt;/code&gt;, &lt;code&gt;mistralai&lt;/code&gt;, or even a local model running on Ollama. Blindfold doesn't care what's in the middle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Protection Methods
&lt;/h2&gt;

&lt;p&gt;Blindfold supports six ways to handle detected PII, depending on the use case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;tokenize&lt;/strong&gt; → &lt;code&gt;&amp;lt;Person_1&amp;gt;&lt;/code&gt; — LLM pipelines, reversible round-trips&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;redact&lt;/strong&gt; → &lt;code&gt;[REDACTED]&lt;/code&gt; — Permanent removal, indexing, storage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;mask&lt;/strong&gt; → &lt;code&gt;J*** D**&lt;/code&gt; — Display to end users, partial visibility&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hash&lt;/strong&gt; → &lt;code&gt;a1b2c3d4...&lt;/code&gt; — Analytics, deduplication without exposing data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;synthesize&lt;/strong&gt; → &lt;code&gt;Jane Smith&lt;/code&gt; — Realistic fake data for testing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;encrypt&lt;/strong&gt; → &lt;code&gt;enc:x8f2k...&lt;/code&gt; — Reversible with encryption key&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Compliance Policies
&lt;/h2&gt;

&lt;p&gt;Each policy defines which entity types to detect and at what sensitivity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;basic&lt;/strong&gt; — Names, emails, phones, locations. Best for general apps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gdpr_eu&lt;/strong&gt; — Adds IBANs, addresses, dates of birth. Best for EU compliance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hipaa_us&lt;/strong&gt; — Adds SSNs, MRNs, medical terms. Best for healthcare.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pci_dss&lt;/strong&gt; — Adds card numbers, CVVs, expiry dates. Best for payment processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;strict&lt;/strong&gt; — All entity types with a lower confidence threshold. Maximum coverage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Data residency is controlled via the &lt;code&gt;region&lt;/code&gt; parameter: &lt;code&gt;"eu"&lt;/code&gt; routes to Frankfurt, &lt;code&gt;"us"&lt;/code&gt; routes to Virginia. Both the API and all SDKs support this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Three steps — tokenize, call the LLM, detokenize — and customer data never leaves our control. It works with any model provider, any framework, and takes minutes to add to an existing codebase. Start locally with zero setup, switch to the cloud API when we need AI-powered accuracy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.blindfold.dev" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/blindfold-dev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://app.blindfold.dev" rel="noopener noreferrer"&gt;Dashboard &amp;amp; API key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Beyond Python, there are SDKs for &lt;a href="https://www.npmjs.com/package/@blindfold/sdk" rel="noopener noreferrer"&gt;JavaScript&lt;/a&gt;, &lt;a href="https://pkg.go.dev/github.com/blindfold-dev/blindfold-go" rel="noopener noreferrer"&gt;Go&lt;/a&gt;, &lt;a href="https://central.sonatype.com/artifact/dev.blindfold/blindfold-sdk" rel="noopener noreferrer"&gt;Java&lt;/a&gt;, &lt;a href="https://www.nuget.org/packages/Blindfold.Sdk" rel="noopener noreferrer"&gt;.NET&lt;/a&gt;, a &lt;a href="https://www.npmjs.com/package/@blindfold/cli" rel="noopener noreferrer"&gt;CLI&lt;/a&gt;, and an &lt;a href="https://www.npmjs.com/package/@blindfold/mcp-server" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt; for AI agent workflows. There's also a &lt;a href="https://github.com/blindfold-dev/langchain-blindfold" rel="noopener noreferrer"&gt;LangChain integration&lt;/a&gt; if we want deeper framework support.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>privacy</category>
      <category>python</category>
      <category>security</category>
    </item>
  </channel>
</rss>
