dumbtv
dumbtv takes the ads, screen tracking and update nags out of your Fire TV over ADB. No root, none of your apps touched, every step can be undone. Free and open source.
Hybrid Rust/Python security scanners for prompt injection, DLP, PII, and agentic tool risks — a layered, on-device AI firewall library.
SecurityRust · PythonGitHub @patronus-protectOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Hybrid Rust/Python security scanners for prompt injection, DLP, PII, and agentic tool risks. A layered, on-device AI firewall library.
Taken from the repository README
Loading the full README.
Read the full README ↗Local security scanning for prompt injection, DLP, PII, and agentic tool risks — in Rust and Python.
Patronus Ark is the open-source scanning engine behind Patronus Protect, an on-device AI firewall. It inspects the text flowing in and out of AI applications — prompts, tool calls, tool outputs, and documents — and classifies the security risk locally, without sending anything to a cloud service.
📖 Documentation · Choose a package · Installation · Quickstart · Python API · Rust API
Patronus Ark comes in two layers. Start with Core unless you need the model-backed categories.
| Ark Core | Ark (full runtime) | |
|---|---|---|
| Packages | patronus-ark-core (crate and PyPI, imports as patronus_ark_core) | patronus-ark (crate and PyPI, imports as patronus_ark) |
| Categories | PII, DLP, prompt injection | eleven categories, including dynamic PII, sensitive documents, agentic tools, routing intent, threat type and shell commands |
| Detection | native L1 rules, plus optional local Wolf Defender inference for prompt injection | L1 rules, NTDB L2 heads and L3 transformers with a trained promote-router |
| Execution | synchronous, on the calling thread; no queue, no worker threads | asynchronous queue with background L3 workers, plus synchronous scan_all() |
| Assets | none for native rules; one Wolf bundle when enabled | L2/L3 model bundles, downloaded on demand or synced offline |
| License | MIT OR Apache-2.0 | GPL-3.0-only or commercial |
Full Ark builds on Core: it runs the same native detectors and the same Wolf runner, so L1
results match between the two. For an HTTP service, ark-api wraps the full
runtime; see Deploy the HTTP API.
Native L1 alone — no model, the same rules in Core and Ark — measured against the established
open-source tools on 2026-10-29 (commit 9cb48cc, dev split, exact span match).
PII vs. Presidio 2.2.364 with tuned recognizers,
Ark in the balanced mode:
| Corpus family | Ark L1 F1 | Presidio F1 |
|---|---|---|
| Neutral public corpora (Gretel finance, ai4privacy) | 67.3 | 40.5 |
| Presidio's own evaluator and recognizer test data | 69.7 | 71.4 |
| Ark's DE/EU synthetic set ¹ | 81.1 | 39.6 |
Ark validates checksums for 69 identifier units, Presidio for 35; neither tool raises a false positive on the hard negatives of the deciding families.
Secrets (DLP) vs. secret scanners, Ark in its default profile:
| Tool | Precision | Recall | F1 | Hard-negative FPs | FPs per MB of benign code |
|---|---|---|---|---|---|
| Ark L1 | 99.3 | 80.0 | 88.6 | 10 | 0.05 |
| gitleaks 8.30.1 | 49.1 | 53.4 | 51.1 | 974 | 0.21 |
| TruffleHog 3.97.9 ² | 63.2 | 36.4 | 46.2 | 326 | 1.43 |
| detect-secrets 1.5.0 | 33.9 | 51.6 | 40.9 | 1,731 | 36.28 |
The DLP scan runs at 8.16 MiB/s against 4.16 MiB/s for gitleaks, with a 100 KiB p95 of 11.7 ms.
¹ Written by us for German and EU identifiers; reported for completeness, not used to decide
milestones. ² Run with --no-verification, so it scores formats only, like the other tools.
These are our own measurements; per-entity results, corpora and method are in
L1 capabilities.
pip install patronus-ark-core # Python 3.11+, wheels include CPU Wolf support
cargo add patronus-ark-core # Rust, native rules only
cargo add patronus-ark-core -F download # Rust, with Wolf inference and asset download
from patronus_ark_core import Scanner
scanner = Scanner({"categories": ["pii", "dlp", "injection"]})
report = scanner.scan("Text to inspect")
for result in report["native"]:
print(result["category"], result["class_name"], result["confidence"])
use patronus_ark_core::{Scanner, ScannerConfig};
let mut scanner = Scanner::new(ScannerConfig::default())?;
let report = scanner.scan("Text to inspect")?;
for result in &report.native {
println!("{} {} {:.2}", result.category, result.class_name, result.confidence);
}
Native rules need no downloads. To add local Wolf inference for prompt injection, point the scanner at a model directory and allow the first warmup to fetch the official bundle:
scanner = Scanner(
{"wolf": {"bundle_dir": "/srv/models/wolf-defender", "threshold": 0.8}},
warmup={"download": "missing"},
)
report = scanner.scan("Text to inspect")
print(report["wolf"]["attack_probability"], report["wolf"]["matched"])
Reports keep native findings (with byte and character evidence spans) and the Wolf result separate; your application decides whether to block or redact. See the Core guide for per-input checks, cancellation and deadlines, and the Core crate README for the full Rust API and Wolf execution options.
pip install patronus-ark # Python 3.11+
cargo add patronus-ark # Rust
See Installation
for model-asset requirements and HF_TOKEN setup. The primary path is the asynchronous queue:
enqueue texts, drain results from the shared queue.
from patronus_ark import SecurityGateway
scanner = SecurityGateway(categories=["injection", "dlp", "pii"], max_level="l2")
scanner.warmup()
# In a real app the consume loop runs on its own thread so you can keep enqueuing —
# see the Quickstart.
scanner.enqueue("Text to inspect")
while (event := scanner.consume_next_event(timeout=1.0)) is not None:
if event["event_type"] == "result":
r = event["result"]
print(r["category"], r["class_name"], r["confidence"])
else:
break # terminal "finished" event
use patronus_ark::{SecurityCategory, SecurityGateway, SecurityLevel};
let mut scanner = SecurityGateway::with_max_level(
vec![SecurityCategory::Injection, SecurityCategory::Dlp],
SecurityLevel::L2,
None, // model dir; None uses the platform cache directory
true, // download missing L2 assets on first warmup
);
scanner.warmup().expect("warmup");
let results = scanner.scan_all("Text to inspect");
A synchronous scan_all() is available in both languages for simple, single-text call sites.
enqueue() returns immediately, results stream back through one
shared queue, and promoted L3 work never blocks ready L1/L2 results.Categories use the layers that fit their detector contract:
| Layer | What it is | Cost | Availability |
|---|---|---|---|
| L1 | Native rule-based detectors (Core and Ark) | input-dependent | no assets; gate-controlled |
| L2 | NTDB packages (shared mmBERT tokenizer/static embedder + lightweight ONNX heads) | milliseconds | Ark, when assets are cached |
| L3 | Full ONNX transformers aligned with L2's tokenizer and embeddings, run by a background worker | tens of ms | Ark, when assets are cached |
Core runs L1 and, when configured, Wolf Defender as a separate prompt-injection model result.
L2 packages carry a trained promote-router that decides when a case actually needs L3, so most traffic never touches a transformer. When a scan is promoted, the queue publishes the L2 fallback first and the final L3 result later. Compatible L2 chunks pass their existing mmBERT token IDs to L3 instead of being tokenized again; L3 errors and timeouts degrade back to L2.
Native-only pii and dlp do not escalate. PII L1 validates deterministic identifiers and
anchor-bound values such as contact, payment, government, account, and employee identifiers. DLP
L1 covers credentials and secrets plus opt-in business identifiers, internal metrics, source code,
SQL, dumps, and logs. All built-in L1 matchers produce source-bound components before a result;
PII and DLP findings return evidence spans, including native operation and MCP rules. Both can
expose non-finding l1_anchors as structured context when execution_gates.explain is enabled.
dynamic-pii is the complementary GLiNER L3 pipeline for semantic entities such as people,
organizations, and locations.
Stable rule gates can disable one native rule without disabling its siblings:
scanner.set_execution_gates({
"rules": {"pii_employee_id": False, "dlp_sql_statement": False},
})
Rust, Python, and the Ark API share credential/secret-only DLP rule defaults;
broader DLP families are available through an explicit gates.rules profile.
Read more: Architecture · Layered scanning · Categories · L1 rule catalog · Models & NTDB · Threat model
Runnable examples for the full runtime live in rust/examples/ and
python/examples/ — basic scan, enqueue/consume, L2→L3 promotion, execution
gates, dynamic PII, cache configuration, and a Dedicated-vs-Multi L3 comparison.
cargo run --example 01_basic_scan
python python/examples/01_basic_scan.py
The examples walkthrough explains
when to use each. Core ships Wolf tooling examples in ark-core/examples/
(bundle preparation and a latency/RSS benchmark).
ark-core/ — patronus-ark-core: synchronous native scanner and optional Wolf runtime, with its
Python bindings in ark-core/python/.rust/ — patronus-ark: the full runtime (levels, queue, L2/L3 models) built on Core.python/ — Python bindings for the full runtime, built with maturin/PyO3, plus the validation
samples used by the built-in local benchmark.ark-api/, ark-coordinator/, ark-distributed-protocol/ — the HTTP service, the L3 fleet
coordinator and their shared wire contract (not published as crates).docs/ — the MkDocs Material site published at
patronus-protect.github.io/patronus-security.cargo fmt --check
cargo test -p patronus-ark-core --features wolf
cargo test -p patronus-ark
cd python && maturin develop && cd ..
.venv/bin/python -m unittest discover -s python/tests
This repository does not accept external contributions. Maintainer documentation: Development · Testing · Releasing
Report vulnerabilities privately — see SECURITY.md. The threat model documents what Patronus Ark does and does not defend against.
ark-core/, including its Python package): MIT OR Apache-2.0. Core-authored
rule catalogs carry the same license; per-rule source_license fields describe upstream
provenance. See ark-core/LICENSE-MIT and
ark-core/LICENSE-APACHE.