<?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: Dillon Roller</title>
    <description>The latest articles on DEV Community by Dillon Roller (@dillonroller).</description>
    <link>https://dev.to/dillonroller</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%2F3828281%2Fd8e0c8ed-bd14-412c-81ab-63e69ce56945.jpg</url>
      <title>DEV Community: Dillon Roller</title>
      <link>https://dev.to/dillonroller</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dillonroller"/>
    <language>en</language>
    <item>
      <title>Stop Sending Raw PII to Your LLM</title>
      <dc:creator>Dillon Roller</dc:creator>
      <pubDate>Tue, 17 Mar 2026 00:23:14 +0000</pubDate>
      <link>https://dev.to/dillonroller/stop-sending-raw-pii-to-your-llm-10f1</link>
      <guid>https://dev.to/dillonroller/stop-sending-raw-pii-to-your-llm-10f1</guid>
      <description>&lt;p&gt;Every time you send a support ticket, log file, or user message to an LLM API, you're potentially leaking emails, phone numbers, credit card numbers, API keys, and more to a third party. Most developers know this is a problem. Most do nothing about it because building a sanitization layer from scratch is annoying.&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://github.com/OxideOps/airlock" rel="noopener noreferrer"&gt;Airlock&lt;/a&gt; to solve this.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;Airlock runs locally before your LLM call. It:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Redacts PII&lt;/strong&gt; — emails, phone numbers, SSNs, credit cards, API keys, JWTs, env secrets, names, and locations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preserves context&lt;/strong&gt; — replaces values with consistent pseudonyms (&lt;code&gt;john@example.com&lt;/code&gt; → &lt;code&gt;user_a1b2@redacted.local&lt;/code&gt;), so the same value always maps to the same alias within a session and your LLM response still makes sense&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compresses tokens&lt;/strong&gt; — strips redundant whitespace, repeated keys, and boilerplate. Typical JSON payloads see 30–60% token reduction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keeps an audit ledger&lt;/strong&gt; — every redaction is logged to a local SQLite database for compliance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No network calls. Nothing leaves your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Python:&lt;/strong&gt;&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;airlock-rs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rust CLI:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;install &lt;/span&gt;airlock-rs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;



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

&lt;span class="n"&gt;data&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;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;john@example.com&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;message&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;My SSN is 123-45-6789 and my API key is sk-abc123xyz&lt;/span&gt;&lt;span class="sh"&gt;"&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;airlock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scrub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&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;scrubbed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# {"user": "user_a1b2@redacted.local", "message": "My SSN is [SSN] and my API key is [API_KEY]"}
&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;Tokens saved: &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;tokens_saved&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;LLM APIs are external services. Even if you trust the provider, you may be subject to GDPR, HIPAA, SOC 2, or other compliance requirements that prohibit sending personal data to third parties without explicit consent.&lt;/p&gt;

&lt;p&gt;Airlock gives you a local firewall you can drop in before any API call — OpenAI, Anthropic, local models, whatever.&lt;/p&gt;

&lt;h2&gt;
  
  
  CLI usage
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'{"email": "jane@example.com", "note": "call her back"}'&lt;/span&gt; | airlock scrub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;airlock scrub &lt;span class="nt"&gt;--input&lt;/span&gt; data.json &lt;span class="nt"&gt;--output&lt;/span&gt; scrubbed.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Open source
&lt;/h2&gt;

&lt;p&gt;Airlock is open source under Apache 2.0. The core is written in Rust for performance and ships as a zero-dependency binary. The Python bindings are built with PyO3.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/OxideOps/airlock" rel="noopener noreferrer"&gt;https://github.com/OxideOps/airlock&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PyPI: &lt;a href="https://pypi.org/project/airlock-rs" rel="noopener noreferrer"&gt;https://pypi.org/project/airlock-rs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;crates.io: &lt;a href="https://crates.io/crates/airlock-rs" rel="noopener noreferrer"&gt;https://crates.io/crates/airlock-rs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Would love feedback — especially on the token compression side, since that's the part that varies the most by use case.&lt;/p&gt;

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