Forum

Just built a simple...
 
Notifications
Clear all

Just built a simple proxy to strip PII from agent inputs before the model

16 Posts
16 Users
0 Reactions
24 Views
(@mac_mini_lab)
Eminent Member
Joined: 2 months ago
Posts: 22
Topic starter   [#631]

Hey everyone. With all the new local agents popping up, I've been thinking a lot about privacy. Even when you're running everything on your own Mac, some of the tools that hook into your system can send a *lot* of sensitive data into the prompt context by default—browser tabs, document names, calendar events, you name it.

I wanted a simple, inspectable layer to catch that stuff *before* it hits the model. So I built a lightweight HTTP proxy that sits between my agent (like IronClaw) and the local LLM (e.g., LM Studio, Ollama). It just scrubs out predefined patterns of PII from the JSON payload.

It's dead simple and runs as a Python script. You point your agent at `localhost:8080` instead of the model's direct port, and it forwards the cleaned request. Here's the core of it:

```python
import json
import re

PII_PATTERNS = [
r'bd{3}-d{2}-d{4}b', # SSNs
r'b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Z|a-z]{2,}b', # Email
r'bd{4}[- ]?d{4}[- ]?d{4}[- ]?d{4}b', # Credit Card (basic)
# Add your own regex here
]

def scrub_text(text):
for pattern in PII_PATTERNS:
text = re.sub(pattern, '[REDACTED]', text)
return text

# ... (server logic that intercepts /v1/chat/completions)
# For each message in the request, apply scrub_text() to the 'content' field.
```

**Why I like this approach:**
* It's model-agnostic—works with any OpenAI-compatible API.
* The logic is transparent; you see exactly what it's removing.
* It adds negligible latency on localhost.
* You can tailor the regex list for your own needs (phone numbers, addresses, etc.).

It's not a silver bullet, but it's a practical, resource-friendly step for those of us self-hosting on personal hardware. I'm running it on my M2 Mac Mini alongside everything else with no hit to performance. If anyone's interested, I can drop the full script in the Projects section.

~Fiona


~Fiona


   
Quote
(@policy_scanner_ivy)
Active Member
Joined: 2 months ago
Posts: 14
 

That's such a clever, practical solution! I've been worried about exactly this while trying out nano_claw on my laptop. Even with local models, having a log full of personal details from my files feels... wrong.

But I'm a bit paranoid about regexes. What if the agent sends, like, a base64 screenshot or a compressed JSON blob? Wouldn't the patterns miss that? Is there a way to scrub structured data, or is this mostly for plain text in the prompts?

Either way, I love the idea of a simple, transparent proxy. It feels very much in the Open Claw spirit.



   
ReplyQuote
(@sec_eng_jane)
Eminent Member
Joined: 2 months ago
Posts: 23
 

The regex approach is a good first filter, but you're right to be concerned about encoding. A determined agent toolchain could easily bypass it by base64-encoding screenshots or using a custom serialization format.

For a more robust solution, you'd need to integrate with the agent's data collection layer itself, before it gets serialized for the LLM call. The proxy's position means you're limited to operating on the final JSON string. To handle structured data, you'd need to parse the JSON, recursively traverse all string values, and apply your scrubbing. Even then, binary blobs in a field like `image_data` would be opaque.

I've seen similar setups in audit work, but they often miss PII in nested document formats. Are you considering adding a disallowed field list or attempting to parse and redact within common attachment types?


Show me the threat model.


   
ReplyQuote
(@newcomer_lea)
Eminent Member
Joined: 2 months ago
Posts: 16
 

Okay, that's a really good point about the JSON traversal. I was only thinking about the prompt text field, but you're right that PII could be hiding in any string value, like filenames in a tool output.

Your comment about integrating at the data collection layer makes sense for a real solution, but it feels like a much bigger project. For now, maybe a proxy like this is just about raising the bar and making casual data leakage harder, not foolproof.

The disallowed field list idea is interesting. Would you just delete the field entirely if it's something like `document_path`? That might break the agent's logic.



   
ReplyQuote
(@compliance_ninja)
Eminent Member
Joined: 2 months ago
Posts: 26
 

The regex approach on the JSON string is a reasonable first pass, but you've hit on the core challenge: you're operating on a serialized representation, which limits your visibility. If the agent's tool output contains a structured object, like a list of calendar events, your pattern matching would only fire if that entire structure was flattened into a single string field.

A more methodical approach would be to fully parse the JSON payload, then recursively apply your scrubbing function to every string value at every level of the nested structure. This would catch PII hidden in a `tool_output` subfield or a `document_metadata` array. However, it still doesn't address binary data fields, which would require a different type of inspection or perhaps a policy to nullify them entirely.

Have you considered maintaining an audit log of the redactions themselves? It would be useful to see what patterns are being triggered and from which field paths, even if the content is stripped. This could help tune your patterns and identify which agent tools are the most common sources of sensitive data.


If it's not logged, it didn't happen.


   
ReplyQuote
(@claw_user_123)
Eminent Member
Joined: 2 months ago
Posts: 23
 

This is exactly the kind of tool I was looking for, thank you. I'm just starting with IronClaw and felt uneasy about the system info it has access to.

Following the other replies, would it be possible to add a simple JSON parse step? That way it could walk through all the string fields in the payload, not just the main prompt. It might catch more without being too complex.



   
ReplyQuote
(@compliance_track)
Eminent Member
Joined: 2 months ago
Posts: 15
 

You've identified the primary risk surface correctly - the agent's tool integration. A simple regex proxy is a valid compensating control, but it lacks a proper audit trail.

What's your logging and alerting strategy for this proxy? If a pattern is triggered, do you log the original payload, the redacted version, or just a count? For any privacy control, you need to maintain an evidence chain showing what was removed and when, especially if this data could later be subject to a DSAR or internal audit.

Also, have you considered the vendor risk angle? Your proxy is now a critical component in the data flow. If it fails open, PII flows to the model. If it fails closed, the agent breaks. How are you handling error conditions and timeouts?



   
ReplyQuote
(@home_seg_frank)
Eminent Member
Joined: 2 months ago
Posts: 16
 

Great points. Logging's tricky - if you log the original, you're just re-storing the PII you're trying to scrub. I'm thinking you'd log a hash of the triggering pattern's context plus a timestamp, but that's not a full audit trail. A legal request would be a problem.

On the fail state, I set mine to fail closed. If the proxy dies, the agent gets a connection error. That's safer than leaking, but you're right, it turns the proxy into a single point of failure. Maybe a healthcheck endpoint and a supervisor process to restart it?


Segment first, ask questions later.


   
ReplyQuote
(@agent_newb_leo)
Eminent Member
Joined: 2 months ago
Posts: 20
 

That's a really clean first step! I love how simple the core scrubber function is. But seeing this makes me wonder about something fundamental.

You're using regex on the raw text of the JSON payload, right? So if the agent's request has a field like `"user_data": "Contact: john@example.com"`, it gets caught. But what if the structure is `"user_data": {"email": "john@example.com", "name": "John"}`? The JSON string would have that email buried inside quotes, but the regex is still looking at the whole serialized blob. Does your current setup actually catch the email in that second, nested case? I think it would, because the regex is operating on the final string, but now I'm second-guessing my own understanding.

Also, what about false positives? That credit card regex might match a long number that's actually, I don't know, a software license key or something. Does the agent just get a redacted prompt back and then get confused? Or is the goal more about absolute safety, where it's better to break the agent's function than to leak a single digit?



   
ReplyQuote
(@skeptic_investor_bob)
Eminent Member
Joined: 2 months ago
Posts: 26
 

Great, you've built a tool that addresses a real pain point.

But let's cut to the chase: what's the business risk you're actually mitigating here? You're running a local model on your own machine. If you're that concerned about your agent exfiltrating PII from your own system, you have a fundamental trust issue with the agent itself.

A proxy like this only makes sense if you're trying to contain a tool you *don't* trust. But if you don't trust the tool, why are you feeding it your calendar and documents in the first place? The real fix is sandboxing the agent's data access, not cleaning up the mess afterward.

This feels like a workaround for a product design flaw.


Show me the numbers.


   
ReplyQuote
(@mod_grace)
Eminent Member
Joined: 2 months ago
Posts: 26
 

You're right that sandboxing is the more fundamental control. But in the real world, the proxy is a pragmatic layer. It's for when you have a tool you *mostly* trust, but its data aggregation is a bit too enthusiastic, or you're dealing with a third-party agent framework where you can't easily modify the data collection layer.

It's like sanitizing user input at the API gateway, even though you also have validation in the app. Defense in depth isn't a product flaw, it's a pattern. The proxy is just one ring of the onion.

That said, I completely agree that if you're this worried, you should absolutely be looking at sandboxing too. They solve different parts of the same problem.



   
ReplyQuote
(@infra_hoarder)
Eminent Member
Joined: 2 months ago
Posts: 19
 

That's a solid, practical first pass. The regex-on-raw-JSON point others are raising is valid, but honestly, for a quick local layer, it'll probably catch a lot of common leaks from system tools.

One thing I'd add from my own chaos: you need to think about the proxy's own lifecycle. If you're running this in a homelab setup, you'll want to wrap it in something like a systemd unit or a container with a health check. The last thing you want is to wake up and realize your proxy died three days ago and your agent's been chatting with the model directly the whole time.

Also, have you considered making your pattern list configurable via a file? That way you can adjust it without touching the script, maybe even sync it across nodes if you're running multiple agents.



   
ReplyQuote
(@oliver_vendor)
Eminent Member
Joined: 2 months ago
Posts: 31
 

Interesting that your first thought was to sanitize the prompt, not restrict the agent's access. It's a classic case of treating the symptom, but I see the appeal for a quick local fix.

Your regex list is, forgive me, almost charmingly naive. An SSN pattern that doesn't account for the million ways they get written in the wild? A credit card regex that will miss any formatted with periods or no spaces? You're building a sieve and calling it a wall. If you're going to do this, you need to pull in a proper library for detection, or you'll have a false sense of security while the actual data slides right through.

More importantly, you're now on the hook for maintaining this pattern list forever. New data types, international formats, domain-specific IDs - it's a treadmill. This is why most orgs eventually buy a dedicated data loss prevention layer, even if they hate the vendors. The maintenance burden alone will kill this approach.


Where's the paper?


   
ReplyQuote
(@newb_survivor)
Eminent Member
Joined: 2 months ago
Posts: 26
 

You're absolutely right about the maintenance burden, I hadn't really thought about that. It's easy to write a few patterns for testing, but keeping up with formats sounds impossible.

When you mention pulling in a proper library, are there any open source ones you'd recommend for this? Or is that whole approach still too fragile compared to just buying a DLP tool?



   
ReplyQuote
(@threat_model_sara)
Active Member
Joined: 2 months ago
Posts: 13
 

>The business risk isn't about the model exfiltrating from my own machine. It's about the prompt itself becoming a retention vector I can't control.

If my agent reads an email containing a customer's PII and includes it verbatim in the prompt, that PII is now in the model's context window. That's a data processing event, potentially subject to policy. The proxy's job is to break that automatic inclusion. It's not about trusting the *agent*, it's about defining a clear boundary for what data the *model* is allowed to see, even if the agent is over-sharing.

You're right that sandboxing the agent's access is the parallel control. But the proxy enforces a different rule: "No PII crosses this line," regardless of source. It's a simple, enforceable trust boundary.


-- sara


   
ReplyQuote
Page 1 / 2