Rust Engine
Admina ships a Rust core engine (admina_core) compiled via PyO3
as a Python extension. The engine provides up to 434× faster governance processing
compared to the pure Python implementation for the full 4-domain pipeline.
Admina auto-detects which engine to use at startup.
Performance
2.08µs 2.33µs 2.50µs 0.62µs 0.67µs 0.71µs 2.38µs 2.67µs 2.75µs 1.00µs 1.12µs 1.25µs 6.25µs 7.04µs 7.29µs
Verified Docker run: Linux aarch64, Python 3.11, single-threaded,
10,000 iterations after 1,000 warmup. Reproduce with
docker build -f Dockerfile.benchmark -t admina-bench . && docker run --rm admina-bench.
7.79µs 2.08µs 3.7× 8.21µs 0.62µs 13.2× 1,992µs 0.62µs 3,213× 505µs 2.38µs 212× 2,261µs 5.21µs 434× Python column includes spaCy NER and sklearn TF-IDF — the production-equivalent path. The large speedup in PII and Loop Breaker reflects replacing ML libraries with compiled Rust.
Selecting the engine
Since v0.10.0 a single switch — ADMINA_ENGINE — selects the
governance-engine backend uniformly across the proxy, the SDK, and the
LangChain/CrewAI callbacks (engines are acquired through one
admina.engines package). This means Admina works identically
without Rust — just slower.
ADMINA_ENGINE=auto— default. Use Rust for the firewall + loop breaker whenadmina-coreis installed, else Python. PII redaction stays on the Python engine for full recall.ADMINA_ENGINE=python— force the pure-Python engines everywhere (broadest detection coverage).ADMINA_ENGINE=rust— force Rust everywhere, including PII (faster, narrower coverage). An unrecognized value raises at startup.
# Check which engine is active curl http://localhost:8080/health # → {"status": "healthy", "engine": {"engine": "rust", "rust_available": true, ...}, ...}
Install — prebuilt wheel
Since v0.9.4 the Rust engine is opt-in via the [rust]
extra. The extra pulls the admina-core wheel from PyPI
and the engine bridge auto-detects it at startup. The extra requires
admina-core>=0.9.3,<0.12, so any core wheel from 0.9.3 up to
the 0.11.x line works with the 0.11.1 framework.
pip install "admina-framework[rust]" python -c "import admina_core; print(admina_core.version())" # → 0.11.1
The project ships as a single Stable-ABI (abi3-py311)
wheel — one artefact works on Python 3.11+ without per-interpreter wheels.
The Rust and Python firewall/PII engines are not equivalent — this is
measured, not assumed. The Rust firewall uses per-pattern severity (matching the Python
InjectionFirewall reporting model) but its pattern coverage is still narrower.
Per the bundled red-team efficacy suite: on the 64-sample injection corpus recall is
57% Python vs 35% Rust, with zero false positives on the 27 negative
samples for both engines. On the 42-sample PII corpus, type-level micro-averaged recall is
100% Python (29/29 expected types) vs 66% Rust (19/29),
with 6 false positives for Python and 0 for Rust across the 16 negative samples. The loop
breaker inverts the picture — 82% Python vs 91% Rust on its 22-sample
corpus, zero false positives on the 11 negatives. The Rust PII scanner also does not cover
EU national IDs or NER person/org names. So under ADMINA_ENGINE=auto
the firewall and loop breaker run on Rust while PII redaction stays on Python for full
recall; ADMINA_ENGINE=rust opts the PII scanner into Rust too. The
pure-Python install has the broadest detection coverage, and the Rust engine wins on raw
throughput (≈6.25µs full-pipeline median).
The coverage gap above is measured, not asserted. Admina ships a red-team
efficacy suite as part of the package (admina/redteam/) that scores three
detectors — injection, PII and loop breaker — against committed corpora (64, 42 and 22
samples) on every engine available in the environment. Run it interactively for a markdown
scorecard:
python scripts/redteam.py
Flags: --engine, --corpus, --format,
--out, --baseline. The pinned baseline lives at
admina/redteam/baselines/baseline.json, and a CI test
(tests/test_redteam_efficacy.py) fails the build on a recall drop or a new
false positive. Measurements are pinned to the engine mode they were taken in, so metrics
from different engine versions are never silently compared. Since v0.11.0 the suite also
scores the optional Microsoft Presidio PII engine as a third column, when
presidio-analyzer and a supported spaCy model are installed. One caveat: the
PII corpus contains only structured identifiers (email, credit card, IBAN, IP, SSN, phone,
Italian codice fiscale, Spanish DNI/NIE) and carries no PERSON/ORG/place expectations —
the regex engine's home ground — so the PII recall column should not be read as a general
verdict on NER-based engines. See
Data Sovereignty for the engine-selection
details.
Note (v0.9.1 hotfix). admina-core 0.9.0 was yanked
from PyPI due to a PyO3 framework-linking bug that aborted at import on Python
versions other than the build host. The [rust] extra pins
admina-core>=0.9.3, so a fresh install never resolves the
yanked wheel.
Mac Intel (x86_64-apple-darwin) wheels are not published;
Intel users build from sdist via the steps below.
Building the Rust engine from source
Prerequisites
- Rust toolchain 1.75+ (rustup.rs)
- Python 3.11+ with development headers
- maturin (
pip install maturin)
Build
# Full build: Rust engine + Python install make all # Or manually cd core-rust maturin develop --release # builds + installs into current venv # Python-only mode (no Rust required) make python
Verify the build
python -c "import admina_core; print(admina_core.version())" # → 0.11.1 python -c "from admina_core import RustFirewall; f = RustFirewall(); print(f.check('test').to_dict())" # → {'is_injection': False, 'risk_level': 'low', 'matched_patterns': [], 'heuristic_score': 0.0, 'heuristic_signals': []}
Rust modules
core-rust/src/firewall.rsRegexSet single-pass injection pattern matching. All 15 patterns compile once into a shared OnceLock RegexSet on first use, so nothing is recompiled per request.
core-rust/src/pii.rsCompiled PII regex scanner. Email, phone, credit card, SSN, IBAN, IP — all patterns pre-compiled into a single pass.
core-rust/src/loop_breaker.rsNormalised term-frequency vectors and cosine similarity over a sliding window for loop detection. Plain HashMap arithmetic — no linear-algebra crate.
core-rust/src/forensic.rsSHA-256 hash chain for the forensic black box. Uses the sha2 crate for zero-dependency hashing.
Running benchmarks
# Full benchmark suite (requires both engines) make bench # Or directly python scripts/benchmark.py # Stress test with 10k requests python scripts/benchmark.py --requests 10000 --concurrency 50
The benchmark generates an HTML report with latency percentiles, throughput curves,
and a Python vs Rust comparison. Reports are saved to benchmark-reports/.
Dockerfile notes
The included admina/proxy/Dockerfile compiles the Rust engine during the Docker build.
If the Rust toolchain is unavailable in the build environment, the build falls back to
Python-only mode automatically (see Makefile targets).
The Dockerfile.benchmark is a separate image for running benchmarks in isolation
without polluting the proxy image.