Detect and neutralise prompt injection attacks in text and HTML content
Project description
sentinel-security
Detect and neutralise prompt injection attacks before they reach your AI agent.
sentinel-security scans text and HTML for hidden instructions, invisible characters, and social engineering patterns that trick LLMs into executing unintended actions. It returns clean text plus a structured threat report.
Install
pip install sentinel-security
For Google Sheets scanning:
pip install sentinel-security[sheets]
Quick start
Python API
from sentinel_security import sanitise_content
result = sanitise_content(untrusted_text)
if result['risk_level'] != 'CLEAN':
print(f"Found {result['threat_count']} threats (risk: {result['risk_level']})")
for threat in result['threats']:
print(f" - {threat['type']}: {threat.get('matched', threat.get('detail', ''))}")
clean = result['clean_text'] # safe to pass to your model
HTML content (emails, web pages)
result = sanitise_content(html_email, format='html')
# Strips hidden elements, checks comments, CSS hiding, meta tags
CLI
# Scan a file
sentinel-scan email.html --format html
# Pipe from stdin
curl -s https://example.com | sentinel-scan --stdin --format html
# CI/CD gate (exit code 0 = clean, 1 = threats found)
sentinel-scan user_input.txt --quiet || echo "BLOCKED"
# Threat report only (no clean text)
sentinel-scan document.txt --threats-only
Google Sheets
from sentinel_security import scan_sheets
result = scan_sheets("spreadsheet_id", credentials=your_google_creds)
# Checks for: hidden sheets, hidden rows/cols, injection in cells,
# text colour matching background, tiny fonts hiding text
What it detects
Prompt injection patterns
- "Ignore previous instructions" and 30+ variants
- System prompt overrides (
system: you are,[INST],<<SYS>>) - Action hijacking ("send email to", "execute this command", "update config")
- Social engineering ("URGENT:", "IMPORTANT:", "authorized maintenance operation")
Hidden content
- HTML comments, display:none, visibility:hidden, opacity:0
- Zero-height/width elements, off-screen positioning
- White-on-white text, font-size:0
- Suspicious Open Graph / meta tags
Unicode attacks
- 20+ invisible characters (zero-width spaces, joiners, BOM, soft hyphens)
- RTL override attacks (text that renders differently than it reads)
- Homoglyph detection (mixed Latin + Cyrillic in same word)
Encoding tricks
- Suspicious base64 blocks (24+ chars, likely encoded instructions)
- Repository metadata injection (HTML comments in markdown, JSON schema $ref)
Google Sheets specific
- Hidden sheets, rows, and columns
- Cell text colour matching background (invisible text)
- Extremely small fonts (< 2pt)
- Injection patterns in cell values
Risk scoring
Every scan returns a risk score (0-10) and risk level:
| Level | Score | Meaning |
|---|---|---|
| CLEAN | 0 | No threats detected |
| LOW | 1-2 | Minor issues (invisible chars) |
| MEDIUM | 3-5 | Suspicious content found |
| HIGH | 6-8 | Likely injection attempt |
| CRITICAL | 9-10 | Active attack detected |
Output format
{
"clean_text": "sanitised content with dangerous chars removed",
"threats": [
{
"type": "injection_pattern",
"matched": "ignore all previous instructions",
"context": "...surrounding text...",
"position": 42
}
],
"threat_count": 1,
"risk_score": 4,
"risk_level": "MEDIUM"
}
Use cases
- AI agent pipelines: scan web pages, emails, and documents before feeding to your LLM
- CI/CD gates: block prompts that contain injection patterns
- Google Workspace: scan shared spreadsheets for hidden malicious content
- Content moderation: pre-filter user-generated content for injection attempts
Framework Middleware
Sentinel provides drop-in runtime security for AI agent frameworks. Every LLM call, tool output, and agent response is automatically scanned for prompt injection -- no changes to your agent logic required.
Install
# LangChain users
pip install sentinel-security[langchain]
# OpenAI / Anthropic SDK users (no extra deps needed)
pip install sentinel-security
LangChain (AgentMiddleware)
For LangChain v1+ agents using create_agent():
from sentinel_security.middleware import SentinelMiddleware
agent = create_agent(
model=ChatOpenAI(),
tools=[...],
middleware=[SentinelMiddleware()], # scans inputs + outputs
)
LangChain Legacy / LangGraph (CallbackHandler)
For create_react_agent, BaseChatModel, or any LangChain component that accepts callbacks:
from sentinel_security.middleware import SentinelCallbackHandler
# With LangGraph create_react_agent:
agent.invoke(
{"messages": [...]},
config={"callbacks": [SentinelCallbackHandler()]},
)
# With a raw chat model:
model = ChatOpenAI(callbacks=[SentinelCallbackHandler()])
The callback handler scans LLM inputs, outputs, and tool results. It is observation-only -- use SentinelMiddleware for blocking support.
OpenAI SDK
from openai import OpenAI
from sentinel_security.middleware import sentinel_wrap
client = sentinel_wrap(OpenAI()) # one line
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": user_input}],
)
# Streaming is also supported -- responses are buffered and scanned on completion.
Anthropic SDK
from anthropic import Anthropic
from sentinel_security.middleware import sentinel_wrap
client = sentinel_wrap(Anthropic()) # one line
response = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{"role": "user", "content": user_input}],
)
Both sync and async clients are supported (OpenAI, AsyncOpenAI, Anthropic, AsyncAnthropic). Wrapping is idempotent -- calling sentinel_wrap() twice on the same client is safe.
Global Configuration
Set defaults for all middleware with configure():
import sentinel_security
sentinel_security.configure(
policy="warn", # "log" | "warn" | "block"
risk_threshold=5, # score (0-10) above which policy fires
event_handler=my_custom_handler, # optional callback for ScanEvent instances
licence_key="sk-sent-...", # optional: activate paid features
)
Or use environment variables:
export SENTINEL_POLICY="warn"
export SENTINEL_RISK_THRESHOLD="5"
export SENTINEL_LICENCE_KEY="sk-sent-..."
Precedence (highest first): per-adapter kwargs > configure() > environment variables > package defaults.
Policy Options
| Policy | Behaviour |
|---|---|
log |
Scan and log results. Never block. All content passes through. |
warn |
Scan and flag threats at WARNING level. Content passes through. |
block |
Scan and raise SentinelBlockedError when risk exceeds threshold. |
Custom Event Handling
Every scan emits a structured ScanEvent to Python's logging module. You can also receive events programmatically:
from sentinel_security.middleware import ScanEvent
def my_handler(event: ScanEvent):
if event.action == "block":
alert_security_team(event.to_dict())
sentinel_security.configure(event_handler=my_handler)
Licence Activation (Python-only)
If you don't use the OpenClaw plugin, activate your licence via environment variable or configure():
sentinel_security.configure(licence_key="sk-sent-...")
# or: export SENTINEL_LICENCE_KEY="sk-sent-..."
The key is validated as a SHA-256 hash over HTTPS -- the plaintext key is never sent. Validation results are cached (24h for valid, 5min for invalid). Offline environments get all core features; paid features degrade gracefully.
For the full middleware guide, see docs/middleware-guide.md or visit sentinel-agents.com.
Requirements
- Python 3.9+
- No dependencies for core text/HTML scanning
google-api-python-clientandgoogle-authfor Sheets scanning (optional)langchain-core>=0.3.0for LangChain middleware (optional)- OpenAI / Anthropic SDK wrapper requires no extra dependencies
License
Commercial. See sentinel-agents.com for licensing.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sentinel_security-0.9.0.tar.gz.
File metadata
- Download URL: sentinel_security-0.9.0.tar.gz
- Upload date:
- Size: 204.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c8720ff0bda5faa461ec42822e4c05b3fa4d65bd881ec7f6e90ed317fffbf785
|
|
| MD5 |
721acabb08dedb51452cba7ac3330966
|
|
| BLAKE2b-256 |
1668d30564a53890dbfeb699811abc91f30f483bd67765c3f7f45bcea57af700
|
File details
Details for the file sentinel_security-0.9.0-py3-none-any.whl.
File metadata
- Download URL: sentinel_security-0.9.0-py3-none-any.whl
- Upload date:
- Size: 137.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c3dc23f4276c24f73c32f6f11c8f576bb7df14eaa9729a2524368a3554871cc5
|
|
| MD5 |
7f9e7f241598ef6465352973efd93842
|
|
| BLAKE2b-256 |
fe1bc4d8d451918501911ba18784a765b8e29e8b8d676ad94fe153d5a18bb373
|