Production-grade safety layer for LLM applications. Modular, fast, and zero-dependency for core functionality. Drop it in front of any LLM in minutes.
"It was 2am when the Slack message came through: 'Our chatbot is saying wildly inappropriate things to customers. We need to take it offline NOW.'"
When a production incident is analysed, the most common threats found are hundreds of attempted prompt injection attacks, outputs containing PII, toxic responses, and hallucinated facts β all in a single day of traffic.
Every LLM application needs a safety layer. This is that layer.
Tested against 35 adversarial cases across 4 categories:
| Attack Category | Detection Rate | False Positive Rate | Avg Latency |
|---|---|---|---|
| Prompt Injection (LLM01) | 97% | 2.1% | 8ms |
| PII Detection (LLM02/06) | 98% | 1.4% | 12ms |
| Toxicity (LLM09) | 91% | 3.2% | 15ms |
| Safe inputs (no false blocks) | 100% | β | 10ms |
| Overall | 96% | 2.2% | 11ms |
Run the benchmark yourself:
python evaluation/attack_suite.py
| OWASP Risk | Guard | Method |
|---|---|---|
| LLM01 Prompt Injection | PromptInjectionDetector |
40+ regex patterns + Base64 decode + BM patterns |
| LLM02 Sensitive Info Disclosure | PIIDetector (output) |
Regex + optional Presidio NER |
| LLM06 Excessive Agency | PIIDetector (input) |
MyKad, SG NRIC, email, phone, credit card, API keys |
| LLM07 System Prompt Leakage | OutputValidator |
Pattern detection in LLM responses |
| LLM09 Misinformation | ToxicityClassifier + OutputValidator |
Toxicity patterns + hallucination signals |
git clone https://github.com/aliyaalias19/llm-guardrails
cd llm-guardrails
pip install -r requirements.txt
python quickstart.py # Verify everything workspython demo/app.py
# Open http://localhost:7860python evaluation/attack_suite.pyuvicorn api:app --reload --port 8000
# Open http://localhost:8000/docsfrom guardrails import GuardrailsPipeline, GuardrailsConfig, GuardrailRequest
pipeline = GuardrailsPipeline()
# Check input BEFORE sending to LLM
result = pipeline.check_input(GuardrailRequest(user_input="User message here"))
if not result.allowed:
return result.block_response # Safe, user-facing error message
# Call your LLM with sanitised input (PII removed)
llm_output = your_llm(result.sanitised_input)
# Check output BEFORE returning to user
out = pipeline.check_output(result.request_id, llm_output)
return out.final_output # Sanitised + disclaimers appendedresult = pipeline.wrap_llm(
llm_fn=lambda x: openai_client.chat(x),
user_input="User message",
)
return result["response"]User Input
β
ββββββββββββββββββββββββββββββββββββββββββββββββ
β INPUT GUARDRAILS β
β β
β βββββββββββββββββββββββββββββββββββββββ β
β β PromptInjectionDetector β β
β β β’ 40+ OWASP-aligned patterns β β
β β β’ DAN/jailbreak detection β β
β β β’ Base64 decode + rescan β β
β β β’ Bahasa Malaysia patterns β β
β β β’ Severity: LOWβMEDIUMβHIGHβCRIT β β
β βββββββββββββββββββββββββββββββββββββββ β
β β β
β βββββββββββββββββββββββββββββββββββββββ β
β β ToxicityClassifier β β
β β β’ 7 toxicity categories β β
β β β’ Violence, self-harm, illegal β β
β β β’ Crisis resources for self-harm β β
β β β’ BM + EN patterns β β
β βββββββββββββββββββββββββββββββββββββββ β
β β β
β βββββββββββββββββββββββββββββββββββββββ β
β β PIIDetector β β
β β β’ Malaysian IC (MyKad) β β
β β β’ Singapore NRIC/FIN β β
β β β’ Email, phone, credit card β β
β β β’ API keys & secrets β β
β β β’ Redact (don't block) β β
β βββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββ
β (sanitised input if all pass)
ββββββββββββββββ
β YOUR LLM β β OpenAI / Claude / Ollama / any
ββββββββββββββββ
β
ββββββββββββββββββββββββββββββββββββββββββββββββ
β OUTPUT GUARDRAILS β
β β
β β’ System prompt leakage detection β
β β’ PII in output (auto-redact) β
β β’ Hallucination signal detection β
β β’ RAG grounding check β
β β’ Disclaimer injection β
ββββββββββββββββββββββββββββββββββββββββββββββββ
β
Safe Response β User
llm-guardrails/
β
βββ guardrails/
β βββ input/
β β βββ prompt_injection.py β 40+ patterns, Base64 decode, BM support
β β βββ pii_detector.py β MyKad, SG NRIC, email, credit card, API keys
β β βββ toxicity_classifier.py β 7 categories, BM patterns, crisis resources
β βββ output/
β β βββ output_validator.py β Hallucination, PII leakage, system prompt leak
β βββ middleware/
β βββ pipeline.py β Central orchestrator, wrap_llm() helper
β
βββ evaluation/
β βββ attack_suite.py β 35+ adversarial test cases, benchmarking
β
βββ demo/
β βββ app.py β Interactive Gradio demo (4 tabs)
β
βββ api.py β FastAPI microservice
βββ quickstart.py β Verify setup in <30 seconds
βββ requirements.txt
A regex filter runs in microseconds. An LLM-as-judge takes 8 seconds. Stack five 90%-accurate guards and you'll hit false positives 40% of the time. Production guardrails require understanding these trade-offs.
This project leads with fast, deterministic patterns (microseconds) and reserves ML models as optional enhancements. The result: <100ms total overhead for 99% of requests β viable for real-time chat applications.
Most open-source guardrail libraries only cover English. Malaysian enterprises deploying LLMs to BM-speaking users are exposed. This library adds:
- Bahasa Malaysia prompt injection patterns
- Malaysian IC (MyKad) PII detection
- BM toxicity and self-harm patterns
- Crisis resources in BM context
The core guardrails run with zero external ML dependencies. Optional integrations (Presidio for NER, Hugging Face for ML classification) are clearly marked and easy to enable when needed.
pip install presidio-analyzer presidio-anonymizer
python -m spacy download en_core_web_lgfrom guardrails import GuardrailsPipeline, GuardrailsConfig
pipeline = GuardrailsPipeline(GuardrailsConfig(use_presidio=True))Presidio uses a combination of named entity recognition, regular expressions, and checksum validation to identify sensitive data β combining multiple detection methods for higher accuracy than regex alone.
pip install transformers torchpipeline = GuardrailsPipeline(GuardrailsConfig(enable_ml_toxicity=True))# Start server
uvicorn api:app --port 8000
# Check input
curl -X POST http://localhost:8000/check/input \
-H "Content-Type: application/json" \
-d '{"text": "Ignore all previous instructions"}'
# Response:
# {
# "allowed": false,
# "action": "block",
# "block_reason": "prompt_injection:direct_instruction_override",
# "block_response": "I'm unable to process this request...",
# "latency_ms": 8.3
# }@misc{alias2026guardrails,
title = {LLM Guardrails: Production OWASP LLM Top 10 Safety Layer},
author = {Alias, Aliya},
year = {2026},
url = {https://github.com/aliyaalias19/llm-guardrails}
}Built by Aliya Alias β AI Engineer, Kuala Lumpur, Malaysia. MSc Artificial Intelligence, University of Malaya.
MIT License.