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
Metadata
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 | Provenance | Actions |
|---|---|---|---|---|
| openclaw_shield-0.1.0.tar.gz | 73.2 kB | Without provenance | Details for openclaw_shield-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| openclaw_shield-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for openclaw_shield-0.1.0-py3-none-any.whl |
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
|
Security for openclaw-shield 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.