Skip to content

taostat/cerberust

Repository files navigation

cerberust

cerberust

Ship LLM features without shipping your users' secrets.

crates.io docs.rs license: MIT OR Apache-2.0

Your model will be handed PII it shouldn't keep, fed API keys pasted into a prompt, and probed with jailbreaks. cerberust is the fast layer that sits between your app and the model and stops it — redacting personal data, masking secrets so they never reach a provider, and blocking prompt injection before a single token is generated.

It's a Rust answer to Python's llm-guard: the same idea — composable scanners you stack in front of a model — built to run compiled, allocation-light, and streaming-safe, with a regex engine that can't be tripped into catastrophic backtracking.

cerberust began as the guardrail layer for gm — confidential, TEE-sealed LLM inference — and is developed in the open as a standalone library.


Why cerberust

  • Fast. The deterministic scanners run compiled Rust over regex automata — one to four orders of magnitude faster than a Python guardrail stack on the same corpus (benchmarks).
  • Streaming-safe by design. A secret split across two streamed chunks is never half-emitted. The runner holds back exactly the bytes that could still be completing a match, and nothing more.
  • Redaction with restore. PII is tokenized on the way in and put back on the way out — your user still reads their own email address in the reply, but the model never saw it. Secrets get the same treatment and are never restored.
  • Cache-stable placeholders, optionally. By default each request mints a fresh random nonce, so the same value redacts differently every time. Opt into deterministic mode and a value's placeholder becomes a keyed function of the value — byte-identical across requests — so a replayed conversation prefix redacts the same way turn after turn and stays friendly to a provider's prompt cache (deterministic redaction).
  • Composable. Scanners are pure text -> verdict functions. Stack them in any order; the stack threads the rewritten text and a shared vault through every one.
  • Extensible and sandboxed. Bring your own patterns with a custom regex scanner, or write a guard in any language, compile it to WebAssembly, and run it with no filesystem, network, or clock — it physically cannot exfiltrate the text it inspects.
  • No surprises. No catastrophic backtracking (linear-time matching, guaranteed), no secrets leaking through error paths, request-scoped state zeroized on drop.

30-second quickstart

[dependencies]
cerberust = "0.1"
use cerberust::{
    GuardrailRunner, MiddlewareChain, Params, PiiScanner, RestoreScanner,
    Scanner, ScannerStack, SecretScanner,
};

// Build a stack: redact PII, mask secrets, restore PII on the way back.
let scanners: Vec<Box<dyn Scanner>> = vec![
    Box::new(PiiScanner::new()),       // email/phone/card/IP/SSN/IBAN -> tokenized
    Box::new(SecretScanner::new()),    // API keys/secrets       -> masked, one-way
    Box::new(RestoreScanner::for_pii()), // PII rehydrated in the response
];
let runner = GuardrailRunner::new("guard", ScannerStack::new(scanners, true));
let chain = MiddlewareChain::new(vec![&runner]);

// chain.generate(Params::new("email alice@example.com, key AKIA…"), &model)
//   -> the model sees redacted text; the email comes back in the reply,
//      the secret never does.

&model is anything implementing the Model trait — point it at your existing client. See Getting started for the full loop, including streaming.

The scanner lineup

cerberust is pass-through by default. Nothing runs until you add it to a ScannerStack, so every scanner is opt-in by construction — you compose exactly the ones you want. The mode below is what each does once you include it. (PromptInjectionScanner and WasmScanner additionally sit behind off-by-default cargo features, since they pull heavy dependencies.)

Scanner Protects you from Mode when added
PiiScanner leaking emails, phone numbers, credit cards, IPs, SSNs, and IBANs to a model provider redact (round-trip — restore in the reply)
SecretScanner API keys, tokens, and private keys pasted into a prompt reaching a provider or being echoed back redact, one-way (never restored)
RegexScanner your own sensitive formats — ticket ids, account numbers, internal tokens redact your patterns
BanSubstringsScanner specific phrases you never want in a prompt or a reply block on match
BanTopicsScanner whole subjects you've ruled out, defined by keywords block on match
TokenLimitScanner oversized prompts blowing your context budget or your bill block when over the limit
RestoreScanner — (the output half that puts redacted PII back in the reply) restores a round-trip scanner
PromptInjectionScanner jailbreaks and "ignore your instructions" attacks block · needs prompt-injection feature
WasmScanner running an untrusted custom guard safely (sandboxed, no egress) runs your guard · needs wasm feature

Benchmarks at a glance

A guardrail's job is to not corrupt the prompt your user paid for — so cerberust optimizes for precision (deterministic regex + checksums), not the recall of a fuzzy NER model that over-redacts ordinary words. Measured against llm-guard on a shared 290-sample corpus (Apple Silicon), comparing only like-for-like:

Same detector, faster runtime — same patterns / same model, so it's a fair race:

Scanner cerberust llm-guard result
Regex (same patterns) 7.81M/s 124.5k/s ~63× faster, identical detection
Ban-substrings (same phrases) 1.16M/s 135.5k/s ~9× faster, identical detection
Prompt-injection (same model) 126/s 96/s tie — byte-identical detection

PII & Secrets — a different approach, on purpose. cerberust's deterministic detectors run at >1.3M/s with perfect precision/recall on structured entities, and don't over-redact — where llm-guard's NER scores 0.75 / 0.89. It's regex vs a neural net, so we don't headline a speed multiple; NER leads on free-text names cerberust deliberately doesn't attempt. Full methodology + honest caveats: docs/benchmarks.md.

Install

[dependencies]
cerberust = "0.1"

Two heavy capabilities are off by default so the core stays lean:

# ML prompt-injection (pulls ONNX Runtime + a tokenizer; downloads a ~739 MB model)
cerberust = { version = "0.1", features = ["prompt-injection"] }

# Sandboxed WASM guards (pulls the wasmtime runtime)
cerberust = { version = "0.1", features = ["wasm"] }

Documentation

From the team behind gm

cerberust is the open-source guardrail library from gm — confidential LLM inference on Bittensor. Point your existing OpenAI, Anthropic, or Gemini SDK at the gm gateway and get identical behavior, sealed inside an Intel TDX enclave so no operator or host ever sees your prompts.

→ saygm.com

License

Licensed under either of MIT or Apache-2.0 at your option.

cerberust ports the scanner-and-stack design pioneered by llm-guard (Protect AI) to Rust. The threat model, the scanner lineup, and the prompt-injection model are its inspiration — with gratitude.

About

No description, website, or topics provided.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors