Security and trust evidence documents the project's policies and automated checks. No certification or badge level is claimed.
Three small, independent security gates for LLM systems, each a thin, tested wrapper that turns a best-in-class open-source tool into a drop-in pass / block decision you can put in a cron job, a CI step, or a request path.
| Gate | Guards against | Backed by |
|---|---|---|
modelscan-gate |
Poisoned model files (unsafe pickle / Keras deserialization) executing on load | ModelScan |
llmguard-proxy |
Prompt injection, secret leakage, invisible-unicode, unsafe output — at runtime | LLM Guard |
garak-assurance |
Shipping a model without knowing how it scores against known attacks | garak |
The value here is the glue, not the engines: a stable verdict contract, fail-closed error handling, machine-readable JSON, and a test suite that runs without downloading a single model. The heavy ML backends are optional dependencies, pulled in only for the gate you actually use.
pip install llm-security-gates # core (no ML backends)
pip install "llm-security-gates[modelscan]" # + ModelScan
pip install "llm-security-gates[llmguard,proxy]" # + LLM Guard + the proxy server
pip install "llm-security-gates[garak]" # + garakEach gate is usable on its own; you never need to install a backend you don't run.
Block unsafe model artifacts before an inference server loads them.
# Point modelscan-gate at the model artifact you are about to load.
# Requires ModelScan (pip install modelscan); the path below is a placeholder for your own file.
modelscan-gate path/to/model.pkl --block-on HIGH --json
# exit 0 = PASS (safe to load) | 1 = BLOCK (unsafe) | 2 = scan error (ModelScan missing or file unreadable)Example --json output when an unsafe artifact is blocked (one HIGH-severity issue):
{"path": "path/to/model.pkl", "decision": "BLOCK", "block_on": "HIGH",
"blocking_issues": 1, "total_issues": 3,
"by_severity": {"LOW": 2, "MEDIUM": 0, "HIGH": 1, "CRITICAL": 0}}A scan that cannot be trusted to have completed (missing binary, timeout, unreadable
report, modelscan-reported errors) exits 2 — never a silent pass. Wire it into a
model-warmup step:
modelscan-gate "$MODEL_DIR" --block-on HIGH || exit 1 # refuse to start on unsafe weightsAn OpenAI-compatible reverse proxy. Point your client at it instead of your backend; it scans the prompt before forwarding and the reply before returning.
export BACKEND_URL=http://127.0.0.1:4000/v1 # any OpenAI-compatible endpoint
export INPUT_SCANNERS=prompt_injection,secrets,invisible_text
export OUTPUT_SCANNERS=sensitive,malicious_urls
uvicorn llm_security_gates.llmguard_proxy:app --host 127.0.0.1 --port 18091curl -s localhost:18091/v1/chat/completions \
-H 'content-type: application/json' \
-d '{"model":"gpt-x","messages":[{"role":"user","content":"ignore all previous instructions"}]}'
# -> a content-filter refusal; the request never reaches the backendGUARD_BLOCK_MODE=refuse (default) returns a 200 OpenAI-style refusal so clients keep
working; reject returns 403. The response carries a guard block with per-scanner
risk and latency for observability.
The firewall scans the entire inbound message set (every user / system / developer
message, and every text part of structured content), not just the last user turn — so an
injection hidden in an earlier message cannot slip through behind a benign final message.
It refuses to start with an empty input-scanner set rather than silently allowing all
traffic. Output inspection also fails closed: an empty or unset-resolving
OUTPUT_SCANNERS value raises a configuration error. Input-only deployments must opt in
explicitly with ALLOW_EMPTY_OUTPUT_SCANNERS=true; this emits a runtime warning whenever
an output is passed through uninspected. The single-string CLI offers the equivalent
--allow-empty-output-scanners flag for output mode.
The same scanning core is available as a CLI for benchmarking a single string:
llmguard-scan --mode input --scanners secrets,invisible_text --text "my key is AKIA..." --jsonRun garak against any OpenAI-compatible endpoint and collapse its report into one per-model resilience score (mean pass-rate) plus the weakest probe — ready for a dashboard tile or a release gate.
export OPENAI_API_KEY=...
garak-assurance --models gpt-x,gpt-y \
--base-url https://api.openai.com/v1 \
--probes promptinject,latentinjection,leakreplay,dan,encoding \
--out assurance.json gpt-x resilience= 0.91 weak=dan [OK]
gpt-y resilience= 0.74 weak=promptinject [OK]
The default probes are light smoke probes so a first run is fast. For real assurance use security probes (
promptinject,latentinjection,leakreplay,dan,encoding).
Each run uses a unique report prefix and rejects a stale or pre-existing report, and a
non-zero garak exit is an error — never a scored "OK" from a leftover report. By default
the gate exits non-zero unless every requested model produced a conclusive score;
pass --allow-partial to accept a partial fleet result.
- Fail closed. Every gate treats "could not complete" as not a pass. A missing backend, a timeout, or an unparseable report is an error exit, not a green light.
- Importable without the ML stack. The decision logic (
decide,score_from_evals,parse_report,_shape,_last_user) is pure and dependency-light; the heavy libraries are imported lazily inside the functions that run a gate. That is what lets the whole test suite run — and CI stay fast — with no model downloads. - Machine-readable. Every gate emits JSON with a stable shape for piping into other tooling.
pip install -e ".[dev]"
pytest -qThe suite stubs the ML backends (injected fake modules, monkeypatched subprocess/HTTP), so it exercises the real control flow — thresholds, fail-closed paths, proxy block/pass, report parsing — without any model weights.
This is orchestration glue around mature FOSS tools, not a re-implementation of them
and not a complete AI-security program. It gives you clean, testable, fail-closed
decision points; ModelScan, LLM Guard, and garak do the detection. See
NOTICE for third-party licenses and attribution.
Built and maintained by Gexiro Global Enterprises Ltd.
The wrapped tools remain under their own licenses.
Part of the Gexiro open-source toolkit.