OpenClaw-Shield 🛡️
Privacy & PII Protection for OpenClaw
OpenClaw-Shield scans your messages and files for sensitive data (PII) before they reach AI models.
🔒 100% Local & Private: All scanning happens on YOUR machine using locally-hosted AI models (GLiNER + Ollama). Your data never leaves your device, never touches the cloud, and is never sent to third-party APIs.
Author: OpenClaw Team
Version: 0.1.0 | March 2026
🎉 Project Status: PRODUCTION READY
✅ MILESTONE COMPLETE: Successfully converted from WebSocket daemon to OpenClaw Skill
✅ Tested & Verified: PII detection working for text, files, and images
✅ Live in Dashboard: Skill shows as eligible in OpenClaw UI
✅ 64+ File Formats: Excel, PDF, CSV, Word, images, code, logs
✅ NSFW Detection: Adult content and inappropriate images blocked
Quick Start
Installation
# Install via pip
pip install openclaw-shield
# Or with all file format support
pip install "openclaw-shield[full]"
Verify Installation
# Check status
openclaw-shield status
# Test scan
openclaw-shield scan "My email is test@example.com" --json-output
What It Does
- 🔍 Scans messages for PII (SSN, credit cards, emails, phones, etc.)
- 🛡️ Protects by detecting sensitive data before AI sees it
- 📁 Files - Scans 64+ file formats (Excel, PDF, CSV, Word, images)
- 🖼️ Images - NSFW detection + PII in photos (passports, credit cards)
- ⚡ Local - Runs entirely on your device via Ollama
- 🔧 Standalone - Works with or without OpenClaw (CLI tool)
🔒 Privacy & Local Processing
Your Data Never Leaves Your Machine
Unlike cloud-based PII detection services, openclaw-shield performs all scanning locally on your own hardware:
| What | How | Where |
|---|---|---|
| Text Analysis | GLiNER NER model (~500MB) | Your local machine |
| Semantic Verification | Ollama LLM (gemma3:3b) | Your local machine |
| Image NSFW Check | Falconsai ViT (~80MB) | Your local machine |
| Image PII Detection | Moondream vision model | Your local machine |
No Cloud Dependencies
- ✅ No API keys needed for OpenAI, Google, or other cloud services
- ✅ No internet required after initial model download
- ✅ No data logging - nothing is stored or transmitted
- ✅ No third-party services - all models run on your hardware
- ✅ Enterprise-friendly - works in air-gapped environments
Perfect for: Healthcare, finance, legal, or any domain where data privacy is critical.
📋 Response Samples
1. Text PII Detection - HIGH RISK
Input:
openclaw-shield scan "My SSN is 123-45-6789 and my email is john.doe@example.com"
Output:
🛡️ OpenClaw Shield Results
⚠️ PII DETECTED - HIGH RISK
Found:
🔴 Social Security Number: XXX-XX-6789
🟡 Email Address: j***@example.com
Confidence: 95%
Risk Level: HIGH
Recommended Action: REDACT before sending to AI
Redacted Version:
"My SSN is [REDACTED-SSN] and my email is [REDACTED-EMAIL]"
2. NSFW Image - BLOCKED
Input:
openclaw-shield scan-file inappropriate_photo.jpg --json-output
Output:
🛡️ OpenClaw Shield Results
🚫 BLOCKED - NSFW Content Detected
Category: Adult/Sexual Content
Confidence: 96%
⚠️ This image has been blocked and was NOT sent to the AI.
Reason: Image contains adult content that violates safety policies.
Action Required: Upload a different image to proceed.
3. PII in Image - Passport Detected
Input:
openclaw-shield scan-file passport_scan.jpg
Output:
🛡️ OpenClaw Shield Results
⚠️ PII DETECTED IN IMAGE - CRITICAL RISK
Found in uploaded image:
🔴 Passport document (readable)
🔴 Full Name (readable)
🔴 Passport Number (readable)
🟡 Face/Portrait (identifiable)
Confidence: 98%
Risk Level: CRITICAL
⚠️ WARNING: This image contains government-issued ID.
Recommended Actions:
1. DO NOT share this image with AI models
2. Crop or blur sensitive areas if you need help with the document
3. Use secure document sharing for identity verification
AI Response: ❌ Blocked - Image not sent to AI
4. File Scanning - CSV with PII
Input:
openclaw-shield scan-file customer_export.csv --json-output
Output:
🛡️ OpenClaw Shield Results for customer_export.csv
⚠️ HIGH RISK - Multiple PII Types Detected
Summary:
📊 File Type: CSV (3 rows analyzed)
🔴 SSNs Found: 3
🟡 Emails Found: 3
🟡 Phone Numbers Found: 3
Risk Assessment: 🔴 CRITICAL
Policy: BLOCK - File not sent to AI
5. Safe Content - No PII Detected
Input:
openclaw-shield scan "The weather is nice today. How can I improve my Python code?"
Output:
🛡️ OpenClaw Shield Results
✅ NO PII DETECTED
Scan Results:
• Personal Information: None found
• Sensitive Data: None found
• Financial Data: None found
• Credentials: None found
Confidence: 99%
Risk Level: NONE
✅ This content is safe to share with the AI.
🗣️ Sample Phrases (OpenClaw Chat)
PII Detection
| Phrase | What Happens |
|---|---|
| "scan this" | Agent scans your message for PII |
| "check for PII" | Agent checks and reports any sensitive data |
| "scan this file" + attachment | Agent scans uploaded file |
| "is this safe to share?" | Agent scans and warns about any PII |
| "redact this" | Agent identifies PII that should be redacted |
NSFW/Images
| Phrase | What Happens |
|---|---|
| "scan this image" + photo | Agent checks for NSFW + PII |
| "is this image safe?" | Content safety verification |
| "check for inappropriate content" | NSFW detection activated |
🤖 Using with OpenClaw (Step-by-Step)
Step 1: Install openclaw-shield
# Automatic installation
curl -fsSL https://raw.githubusercontent.com/openclaw/openclaw-shield/main/install.sh | sh
# Or manual
pip install openclaw-shield
ollama pull gemma3:3b
ollama pull moondream
Step 2: Install the Skill
openclaw-shield skill install --global
Step 3: Verify
openclaw skills list | grep openclaw-shield
# Should show: ✓ ready | 🛡️ openclaw-shield
Step 4: Use It
In OpenClaw chat, simply type:
"scan this: My SSN is 123-45-6789"- Scans text"scan this file"+ attachment - Scans files"scan this image"+ photo - Checks images
🖥️ Using OpenClaw-Shield Standalone & From Other Apps
openclaw-shield works completely independently as a command-line tool. You don't need OpenClaw installed to use it.
1. Standalone CLI Usage
Text Scanning
# Basic scan (human-readable output)
openclaw-shield scan "My SSN is 123-45-6789"
# JSON output (for scripting)
openclaw-shield scan "Contact me at john@example.com" --json-output
# Pipe from other commands
echo "My credit card is 4532-1234-5678-9012" | openclaw-shield scan -
# Read from file
cat sensitive_email.txt | openclaw-shield scan -
File Scanning
# Any file type (auto-detected)
openclaw-shield scan-file document.pdf
openclaw-shield scan-file data.xlsx --json-output
openclaw-shield scan-file photo.jpg # Includes NSFW check
# Batch scan directory
for file in ~/downloads/*.csv; do
openclaw-shield scan-file "$file" --json-output
done
2. Integration with Other Applications
Shell Scripts
#!/bin/bash
# pre-commit-hook.sh - Check files before git commit
FILES=$(git diff --cached --name-only)
for file in $FILES; do
if [[ $file =~ \.(txt|csv|json|py|js)$ ]]; then
RESULT=$(openclaw-shield scan-file "$file" --json-output)
if echo "$RESULT" | jq -e '.flagged' > /dev/null; then
echo "❌ Commit blocked: $file contains PII"
echo "$RESULT" | jq '.categories'
exit 1
fi
fi
done
echo "✅ No PII detected in changed files"
Python Applications
import asyncio
from openclaw_shield import load_config
from openclaw_shield.scanner.text import TextScanner
from openclaw_shield.scanner.image import ImageScanner
async def scan_user_input(user_message):
"""Scan before sending to any AI API"""
config = load_config()
scanner = TextScanner(config)
result = await scanner.scan(user_message, surface="api")
if result.flagged:
return {
"safe": False,
"pii_types": result.categories,
"confidence": result.confidence,
"recommendation": "REDACT" if result.confidence > 0.8 else "REVIEW"
}
return {"safe": True}
# Usage in your app
async def main():
user_msg = "My email is user@example.com"
check = await scan_user_input(user_msg)
if not check["safe"]:
print(f"⚠️ PII detected: {check['pii_types']}")
# Don't send to AI
else:
# Safe to proceed
pass
Node.js / JavaScript Apps
const { execSync } = require('child_process');
function scanForPII(text) {
try {
const result = execSync(
`openclaw-shield scan "${text}" --json-output`,
{ encoding: 'utf-8' }
);
return JSON.parse(result);
} catch (error) {
return { flagged: false, error: error.message };
}
}
// Express middleware example
app.post('/api/chat', (req, res) => {
const userMessage = req.body.message;
const scan = scanForPII(userMessage);
if (scan.flagged) {
return res.status(400).json({
error: "PII detected",
types: scan.categories,
message: "Please remove personal information before sending"
});
}
// Proceed to AI
});
Docker Applications
# Dockerfile
FROM python:3.11
# Install openclaw-shield
RUN pip install openclaw-shield
# Your app
COPY . /app
WORKDIR /app
CMD ["python", "app.py"]
# In your containerized app
import subprocess
def scan_file(filepath):
result = subprocess.run(
['openclaw-shield', 'scan-file', filepath, '--json-output'],
capture_output=True,
text=True
)
return json.loads(result.stdout)
# Scan uploaded files
@app.route('/upload', methods=['POST'])
def handle_upload():
file = request.files['file']
filepath = f"/tmp/{file.filename}"
file.save(filepath)
scan_result = scan_file(filepath)
if scan_result['flagged']:
os.remove(filepath) # Delete immediately
return "File contains PII - rejected", 400
3. Workflow Integrations
Slack Bot
# slack_bot.py
from slack_bolt import App
app = App()
@app.message()
def handle_message(message, say):
text = message['text']
# Scan before processing
import subprocess
result = subprocess.run(
['openclaw-shield', 'scan', text, '--json-output'],
capture_output=True,
text=True
)
scan = json.loads(result.stdout)
if scan['flagged']:
say(f"⚠️ This message contains PII: {scan['categories']}")
say("Consider sending in a DM instead")
Discord Bot
# discord_bot.py
import discord
import subprocess
class MyBot(discord.Client):
async def on_message(self, message):
if message.author == self.user:
return
# Scan attachments
for attachment in message.attachments:
if attachment.filename.endswith(('.txt', '.csv', '.pdf')):
await attachment.save(f"/tmp/{attachment.filename}")
result = subprocess.run(
['openclaw-shield', 'scan-file', f"/tmp/{attachment.filename}", '--json-output'],
capture_output=True,
text=True
)
scan = json.loads(result.stdout)
if scan['flagged']:
await message.channel.send(
f"🛡️ {attachment.filename} contains PII: {scan['categories']}"
)
Zapier / n8n Webhooks
# Webhook receives file, scan before processing
curl -X POST http://localhost:3000/scan \
-F "file=@document.pdf" \
-F "callback=https://hooks.zapier.com/..."
# Server side
openclaw-shield scan-file uploaded.pdf --json-output | \
jq '{safe: (.flagged | not), categories: .categories}'
4. CI/CD Pipeline
GitHub Actions
# .github/workflows/pii-check.yml
name: PII Check
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install openclaw-shield
run: pip install openclaw-shield
- name: Scan repository for PII
run: |
find . -name "*.txt" -o -name "*.csv" -o -name "*.json" | \
while read file; do
RESULT=$(openclaw-shield scan-file "$file" --json-output)
if echo "$RESULT" | jq -e '.flagged'; then
echo "❌ PII found in $file"
exit 1
fi
done
5. API Wrapper (Create Your Own)
# shield_api.py - Flask wrapper
from flask import Flask, request, jsonify
import subprocess
app = Flask(__name__)
@app.route('/scan/text', methods=['POST'])
def scan_text():
text = request.json.get('text', '')
result = subprocess.run(
['openclaw-shield', 'scan', text, '--json-output'],
capture_output=True,
text=True
)
return jsonify(json.loads(result.stdout))
@app.route('/scan/file', methods=['POST'])
def scan_file():
file = request.files['file']
filepath = f"/tmp/{file.filename}"
file.save(filepath)
result = subprocess.run(
['openclaw-shield', 'scan-file', filepath, '--json-output'],
capture_output=True,
text=True
)
import os
os.remove(filepath)
return jsonify(json.loads(result.stdout))
if __name__ == '__main__':
app.run(port=5000)
Usage:
curl -X POST http://localhost:5000/scan/text \
-H "Content-Type: application/json" \
-d '{"text": "My SSN is 123-45-6789"}'
6. Database / Data Pipeline
# data_pipeline.py
import pandas as pd
import subprocess
import json
def sanitize_dataframe(df):
"""Scan and flag PII in pandas DataFrame"""
flagged_columns = []
for column in df.columns:
# Sample first 10 rows
sample = ' '.join(df[column].astype(str).head(10))
result = subprocess.run(
['openclaw-shield', 'scan', sample, '--json-output'],
capture_output=True,
text=True
)
scan = json.loads(result.stdout)
if scan['flagged']:
flagged_columns.append({
'column': column,
'pii_types': scan['categories']
})
return flagged_columns
# Usage
df = pd.read_csv('customer_data.csv')
pii_columns = sanitize_dataframe(df)
print(f"PII detected in columns: {pii_columns}")
Summary: Integration Methods
| Method | Best For | Complexity |
|---|---|---|
| CLI + Shell Scripts | Git hooks, CI/CD, automation | ⭐ Easy |
| Python API | Python apps, data pipelines | ⭐⭐ Medium |
| Subprocess (Node/Go/etc) | Non-Python apps | ⭐ Easy |
| HTTP API Wrapper | Microservices, web apps | ⭐⭐⭐ Advanced |
| Docker | Containerized environments | ⭐⭐ Medium |
The CLI is completely self-contained - use it anywhere you can run shell commands! 🛡️
Supported File Formats
Documents
- Text: .txt, .rtf, .md, .docx, .pdf
- Excel: .xlsx, .xls
- Data: .csv, .tsv, .json, .yaml, .xml
Code & Logs
- Python: .py
- JavaScript: .js, .jsx, .ts, .tsx
- Java/C: .java, .c, .cpp, .h
- SQL: .sql
- Shell: .sh, .bash, .zsh, .ps1
- Logs: .log, .out
Images
- Formats: .png, .jpg, .jpeg, .gif, .webp, .tiff, .bmp
- NSFW Detection: Adult content blocked
- PII Detection: Passports, credit cards in photos
Total: 64+ file formats supported!
Documentation
| File | Description |
|---|---|
skill/references/INSTALLATION.md |
Detailed install guide |
skill/references/USAGE.md |
Usage examples |
skill/references/TROUBLESHOOTING.md |
Common issues |
skill/references/CONFIGURATION.md |
Config options |
skill/references/ENTITY_TYPES.md |
Supported PII types |
MILESTONES.md |
Project milestones |
TEST_RESULTS.md |
Testing documentation |
Testing Results
All tests passed ✅:
| Test | Result |
|---|---|
| SSN detection | ✅ Found |
| Email detection | ✅ Found |
| Phone detection | ✅ Found |
| CSV scanning | ✅ All PII found |
| Code scanning | ✅ Credentials detected |
| Skill installation | ✅ Shows as eligible |
| System status | ✅ All dependencies OK |
License
MIT License - See LICENSE for details.
Acknowledgments
- GLiNER - Zero-shot NER model
- Ollama - Local LLM inference
- OpenClaw - Agent framework with skill system
- Falconsai - NSFW image detection model
Release files for openclaw-shield 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| openclaw_shield-0.1.0.tar.gz | 73.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| openclaw_shield-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 116.9 kB
Release files / openclaw_shield-0.1.0.tar.gz
| Download URL | openclaw_shield-0.1.0.tar.gz |
|---|---|
| Size | 73.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e6c31e95bfdb8b16ac209a4bd1805b67b4b579c71c15aa4d8ce0e7eb58e93e6a
|
|
BLAKE2b-256 checksum How to use checksums |
e8fab5279fb03a623820c65148e02d2a62adccc0c3f9f7f0ea40e175c64552f0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.1
|
Release files / openclaw_shield-0.1.0-py3-none-any.whl
| Download URL | openclaw_shield-0.1.0-py3-none-any.whl |
|---|---|
| Size | 43.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
68e71c378539fb8a1592c4394d3fb784de18fa4da0e3cb3cd91dc73bb9120169
|
|
BLAKE2b-256 checksum How to use checksums |
d6c51d6707bdd7c7ade8addee888bd5631da8172bd0c132fb1946fc6eed7f0a3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.1
|