Ben @ Grepture

LLM Guard Is Archived: Alternatives and Migration Guide

LLM Guard's repo went read-only in July 2026. What that means for production deployments, how to pick an LLM Guard alternative, and how to migrate.

The default open-source guardrails library just stopped moving

On July 9, 2026, the llm-guard repository was archived on GitHub. The code is still there, the MIT license still applies, and pip install llm-guard still works. But the repo is now read-only: no more commits, no more merged PRs, no more issue triage. If you run LLM Guard in production, you're now running unmaintained security software on your AI traffic, and it's time to look at an LLM Guard alternative.

This post covers what "archived" actually means for a security dependency, how to inventory what you're really using LLM Guard for (usually less than you think), and how to migrate, including the option of moving guardrails out of your application code entirely and onto the network path.

What happened

LLM Guard came out of Protect AI as an open-source Python toolkit: 35+ scanners covering PII anonymization, secret detection, prompt injection, toxicity, bias, code detection, and output validation. Comprehensive, MIT-licensed, and free, it quickly became the default answer to "how do I add guardrails to my LLM app."

The trajectory since has been the familiar one for venture-backed open source. Protect AI was acquired by Palo Alto Networks, development slowed through 2025 and early 2026, and in July the repo was formally archived. Priorities shift after an acquisition, and archiving is more honest than letting a repo rot silently. For users, though, the practical outcome is the same either way.

It's also part of a broader consolidation wave. Helicone went into maintenance mode after its acquisition, Humanloop was sunset after joining Anthropic, and Private AI rebranded and refocused. The tooling landscape teams standardized on in 2024–2025 is being rearranged underneath them.

What "archived" means for a security dependency

An archived utility library is an inconvenience. An archived security library is a liability, because the thing you depend on it for (keeping up with a moving threat landscape) is exactly what stops happening. Concretely:

  • No vulnerability patches. If a CVE lands in LLM Guard itself or in its heavy dependency tree (transformers, torch, spaCy), there is no upstream fix coming. You patch it in a fork or you don't patch it.
  • No new detection patterns. New credential formats ship constantly, and every provider that launches a new API key format is invisible to a frozen Secrets scanner. Prompt-injection techniques evolve even faster; OWASP's 2026 report measured prompt injection attempts up 340% year over year. A detection model frozen in time decays against an adversary that doesn't.
  • Dependency rot. LLM Guard pins against specific versions of the Hugging Face stack. As the ecosystem moves, you'll increasingly choose between holding back your entire Python environment or maintaining compatibility patches yourself.
  • No model updates. The transformer models behind the Anonymize, PromptInjection, and Toxicity scanners will never be retrained. Their recall was already the tuning-heavy part of running LLM Guard; now the ceiling is fixed.

None of this bites on day one. All of it bites eventually, and security dependencies are the worst place to find out when.

First, inventory what you actually use

LLM Guard ships 35+ scanners, but almost nobody runs 35 scanners. Each one adds latency (100ms to several seconds for the model-based ones), so most teams converge on a small core. Before evaluating replacements, grep your scanner configuration and write down what's actually in the chain. In practice it's usually some subset of:

from llm_guard import scan_prompt
from llm_guard.input_scanners import Anonymize, Secrets, PromptInjection, Toxicity

scanners = [Anonymize(), Secrets(), PromptInjection(), Toxicity()]
sanitized_prompt, results, valid = scan_prompt(scanners, prompt)

That is: PII anonymization, secret detection, prompt injection detection, and sometimes toxicity. The long tail (bias, gibberish, code detection, reading time, JSON validation) tends to be either unused or trivially replaceable with a few lines of your own code.

This inventory matters because "replace LLM Guard" is a much bigger project than "replace the four scanners we actually run." Scope the migration to the second one.

Choosing an LLM Guard alternative: three paths

Path 1: Another Python library

You can swap in other open-source components per scanner: Microsoft Presidio for PII detection, a standalone secrets scanner for credentials, NeMo Guardrails or a classifier model for content policy.

This keeps the same architecture, a scanner chain inside your application, which is both its appeal and its problem. You keep full control and zero vendor dependency, but you inherit the same operating model that made LLM Guard expensive to run well: model hosting, threshold tuning, per-language coverage, and now multiple libraries' upgrade treadmills instead of one. And Presidio specifically is a detection toolkit rather than a redaction system, with no secrets support, one-way anonymization, and no audit trail. We've written up where Presidio stops and what production redaction needs beyond it; the short version is that it replaces LLM Guard's Anonymize scanner, not LLM Guard.

Choose this path if you have a team that genuinely wants to own guardrails as an internal system, or if you rely on LLM Guard's long-tail scanners (bias, code detection, output validation) that gateway products don't cover.

Path 2: Fork and freeze

You can fork the archived repo and maintain it privately. This is the right call for exactly one situation: a hard compliance requirement that all security tooling runs from source you control, plus the staffing to actually review and patch a transformer-based Python codebase indefinitely.

Be honest about the second half. A fork that nobody actively maintains is the archived repo with extra steps. You've taken on the liability without removing any of it.

Path 3: Move guardrails to the network layer

The third option is to stop scanning inside your application and put the checks on the network path instead: an AI gateway that sits between your app and the provider, scanning every request in transit.

This is a genuine architecture change, not a drop-in swap, so it's worth being clear about what changes:

Scanner chain (LLM Guard)Gateway
IntegrationExplicit call at every code pathChange the base URL once
CoverageOnly paths you remembered to wrapEvery request, including agents and third-party SDKs
Latency100ms–5s per model scannerSingle-digit ms for regex-class checks
LanguagesPython onlyAny language (HTTP-level)
RedactionOne-way placeholdersReversible mask-and-restore possible
MaintenanceYours (models, thresholds, upgrades)The gateway's
Audit trailBuild it yourselfBuilt in
Long-tail scannersBias, code, output validationUsually not covered

The coverage row is the one that changed my mind about scanner chains in general. A library only runs where you call it. Every new endpoint, background job, and, increasingly, autonomous agent making tool calls you didn't hand-write is a chance to skip the scan. In mid-2026, with agent frameworks multiplying egress paths faster than anyone can code-review them, "did we wrap every call site?" is a question application-level scanning can no longer answer confidently. A proxy answers it structurally: if the traffic leaves, it was scanned.

The latency row matters at a different scale. LLM Guard's model-based scanners were the tax you paid for breadth: half a second to several seconds per request, on GPU infrastructure you hosted. Network-level scanning with deterministic validators and optimized models runs in milliseconds. For chatbots and agent loops making dozens of calls per task, that difference is user-visible.

Migrating: what the before and after looks like

Here's the shape of the migration for the common case, the four-scanner chain above in a Python app calling OpenAI.

Before, every call site threads through the scanner chain:

scanners = [Anonymize(vault), Secrets(), PromptInjection(), Toxicity()]

def safe_completion(prompt: str):
    sanitized, results, valid = scan_prompt(scanners, prompt)
    if not valid:
        raise GuardrailViolation(results)
    return client.chat.completions.create(
        model="gpt-5.5", messages=[{"role": "user", "content": sanitized}]
    )

After, the application code stops knowing guardrails exist. You point the SDK at the gateway and the checks happen in transit:

client = OpenAI(
    base_url="https://gateway.example.com/v1",  # your gateway endpoint
    api_key=os.environ["GATEWAY_KEY"],
)

def safe_completion(prompt: str):
    return client.chat.completions.create(
        model="gpt-5.5", messages=[{"role": "user", "content": prompt}]
    )

The Vault object in that first snippet deserves a note, because it's a migration gotcha. LLM Guard's Anonymize scanner could store placeholder mappings in a Vault so a Deanonymize output scanner could restore them. But the mapping lived in your process, per-instance, with lifecycle management left to you. If you used this, make sure your replacement supports reversible redaction natively; if you never used it, gateway-side mask-and-restore is a capability you gain in the move: the model sees placeholders, your users see real values, and the mapping never depends on which app instance handled the request.

Two more things to migrate deliberately rather than by default:

  • Blocking behavior. scan_prompt returned a validity flag and your code decided what to do. Gateways express this as policy: block, redact, or flag-and-log per category. Port your actual decisions, not the scanner list.
  • The long tail. If you genuinely used bias detection or output validation, those don't map to gateway features. Keep a minimal in-app check for just those, and let the network layer own PII, secrets, and injection.

How Grepture covers the migration

Grepture is an AI gateway with the security layer built in, and the four-scanner core maps directly onto it:

  • Anonymize → PII redaction: 50+ deterministic patterns plus multilingual NER models, running in-process at the proxy, so raw prompts are never fanned out to a third-party detection API. Reversible mask-and-restore is native, replacing the Vault/Deanonymize pattern with consistent tokens across a whole conversation.
  • Secrets → secret scanning: purpose-built patterns for 30+ credential types (API keys, bearer tokens, AWS credentials, connection strings), which is one of the highest-severity leak categories in LLM traffic and the place where frozen patterns decay fastest.
  • PromptInjection → injection detection: scanning at the gateway, covered in depth in our prompt injection prevention guide.
  • Toxicity → content scanning on the Business plan, using locally-hosted models.

Because it's a proxy, the same protection applies to every language and framework in your stack, not just Python. The integration is a base-URL change whether the caller is a Node service, a CrewAI agent, or a coding assistant. Every scan lands in an audit trail you can hand to a compliance team, which under GDPR and the EU AI Act's transparency obligations is no longer optional paperwork.

We maintain a full feature-by-feature Grepture vs. LLM Guard comparison. It was written while LLM Guard was still maintained, and the scanner-coverage tradeoffs it describes still apply to the frozen version. And if your policy requires running from source, the proxy core is open source and self-hostable.

LLM Guard earned its place as the default, and the archived code will keep working for a while. But a guardrails layer is only as good as its last update, and that date is now fixed. Whichever path you take, take it before the gap starts to show in your traffic.

[Protect your API traffic today]

Start scanning requests for PII, secrets, and sensitive data in minutes. Free plan available.

Get Started Free