We use cookies to enhance your experience on the site
CodeWorlds
Back to collections
Guide13 min read

Protect AI, model scanning and LLM Guard

Protect AI moved into Palo Alto Networks, ModelScan lives on, and LLM Guard has been archived. Pickle attacks, model scanning, and a practical rollout.

Protect AI, model scanning and LLM Guard

Protect AI worked on machine learning supply chain security: checking whether a downloaded model executes code on load, and filtering what enters and leaves a language model. The company no longer exists on its own, and of its two open tools only one is still being developed.

The problem it addresses gets dismissed, since it does not look dangerous. You download a model file from a public repository and load it in two lines of code. In the popular format that file is a program rather than data, so loading it means running it.

The company vanished, the tools stayed

Palo Alto Networks announced its intent to acquire in April 2025, and the deal closed on the twenty second of July that same year.

That was not an isolated case. The same year SentinelOne bought Prompt Security and Check Point took Lakera: independent AI security companies moved into large vendors, and with that self serve signup gave way everywhere to a sales conversation. When comparing offers from this segment, assume you will not find a price list.

The commercial products moved into the Prisma AIRS platform: the model scanner, adversarial testing, and runtime observation operate there as its components. Sales run through that vendor's enterprise channel, so there is no price list and the conversation starts with a salesperson.

For a developer, what stayed outside that change matters more. The tool scanning model artefacts remains open under Apache 2.0, and the library filtering prompts and responses under MIT. Both drop into a project without talking to anybody.

The two tools have parted ways, though, and that is the first thing to check before picking one. The artefact scanner is alive: its latest release is 0.8.8, from February 2026. The filtering library was archived on GitHub in July 2026, and its maintainers wrote plainly in the readme that the project and its associated models are no longer under active development or maintained. Its last release in the package registry is 0.3.16, from May 2025. The code still installs and still runs, but new detectors, refreshed classification models, and security fixes are not coming.

Keep that distinction in mind when reading material about this. Plenty of writing describes the commercial platform's capabilities under the name of a company that is no longer a separate entity, which makes it easy to confuse what you get for free with what has to be bought.

What a serialisation attack is

Worth understanding, since without it model scanning looks like excessive caution.

Python's default object serialisation format stores not data but instructions for reconstructing an object. Among those instructions sits the ability to call any function with any arguments. Loading such a file executes those instructions before you see any output at all.

The consequence is simple and unpleasant: a model file downloaded from a public repository can open an outbound connection, read environment variables holding keys, or add itself to scheduled tasks. It happens at load time, under the account of whoever loaded it, and with no message.

What makes it particularly nasty is that a model modified this way behaves normally. It returns the same results as the original, so quality tests catch nothing. The only thing that changed happens outside the model.

The scale of the problem follows from how work happens. Pulling models from public repositories is daily routine in this field, and the repository name is often the only verification. That is the same class of risk as installing a package named deceptively close to a popular one, except fewer people think about it.

The model scanner in practice

Code
Bash
pip install modelscan
modelscan -p ./models/classifier.pkl

The tool supports several artefact formats, among them Python serialisations, formats used by popular machine learning libraries, and saved model graphs. It checks whether the file contains calls capable of executing code and returns a list of findings with a risk level.

Scanning a whole directory before using anything looks like this:

Code
Bash
modelscan -p ./models --reporting-format json > report.json

Structured output slots into a build pipeline. That is the right home for this tool: not a manual run once a quarter but a step that blocks a deployment when the scan returns a high risk finding.

Two things deserve knowing before you consider the matter closed. The scanner detects known patterns of dangerous calls, so it is not proof of safety but a sieve for what is known. And: a clean scan speaks about code in the file rather than about the behaviour of a model that may have been trained to give bad answers to particular queries.

The format that fixes it at the source

Scanning is patching. The real fix is a storage format holding numbers alone.

The safe tensor format, adopted as the default in the largest model repository, contains no execution instructions, so loading a file cannot run code. It also loads faster, since it permits mapping the file into memory instead of rewriting it whole.

The practical rule is short: if a model is available in that format, take it and the problem disappears. If it exists only in an executable format, scan before loading, and better still convert it once in an isolated environment and work on the safe version from then on.

Conversion gets skipped because it looks like extra work, while it happens once per model and removes an entire class of risk from a team's daily routine. For models run locally, through Ollama for instance, the format is usually handled by the tool, but with your own weights or internally fine tuned models the decision is yours.

Filtering prompts and responses

The second open library in this set does something entirely different: it handles content entering and leaving a language model. Everything below describes a project frozen in July 2026, so read it as a description of a final state rather than of something still growing.

The set covers more than a dozen input checks and around twenty output checks. On the input side sit detection of injections, personal data, access tokens, and toxic content. On the output side come relevance to the question, detection of unreachable and malicious links, and sensitive data in the response.

Code
Python
from llm_guard import scan_prompt
from llm_guard.input_scanners import Anonymize, PromptInjection

scanners = [Anonymize(vault), PromptInjection()]
sanitised, valid, risk = scan_prompt(scanners, user_prompt)

if not all(valid.values()):
    raise ValueError(f"Prompt rejected, risk scores: {risk}")

Everything runs locally, in your process, so content never leaves your infrastructure. That is the main difference from services such as Lakera Guard or Prompt Security, where the text travels to somebody else's server.

The price is predictable. Some checks use classification models, so the first run downloads weights and every check costs processor or graphics card time. With ten checks enabled the latency becomes noticeable, and you have to select the ones genuinely needed rather than switching everything on.

Where a model came from, and why that is hard

Scanning answers whether a file contains dangerous code. It does not answer whether the file is what it claims to be, and that is a separate problem.

A traditional software supply chain gives you signatures, checksums, and package registries with release history. With models it is worse. Public repositories let anyone open an account named deceptively close to a known organisation, publish a model whose name suggests official provenance, and collect downloads from people copying the name out of a web page.

A fine tuned model additionally carries multi step provenance: somebody took another party's weights, trained further on their own data, and published the result. Establishing exactly what entered the training data at any stage is in practice impossible.

The practical minimum looks like this. Record the checksum of the file you used, along with the version and the source address. Keep a copy in an internal repository rather than downloading on every deployment, since a file at the same address can change. Restrict the list of organisations you may pull from to one somebody can actually review.

That sounds like bureaucracy until an advisory lands about a vulnerable artefact and the question arrives whether it affects you. A team with a registry answers in fifteen minutes; a team without one searches machines for three days.

Adversarial testing and what it gives you

A separate category is checking how a model behaves under deliberate attack rather than under ordinary use.

It works by generating a set of queries trying to bypass constraints, extract the system prompt, or force an answer outside the permitted range, then counting how many succeeded. The result is a number, and that is its main value.

The difference from filtering is fundamental. A filter runs while the application runs and stops individual requests. Adversarial testing runs before deployment and before a system prompt change, and the result tells you whether the change made things worse.

In the commercial version it is a separate platform product. In a minimal version your own set of a hundred queries, stored in the repository and run on every prompt change, suffices. It lacks the precision of a dedicated tool, while catching the most common case: a prompt tweak that incidentally opened something previously closed.

Protect AI against the alternatives

OptionScopeHow it runsPick it when
Model scannerModel artefactsLocally, command lineYou pull models from public repositories
Filtering libraryPrompts and responsesLocally, a library, project archivedData cannot leave your infrastructure and frozen development is acceptable
Guardrails AIPrompts and responsesLocally, validators as codeRules expressed in project code
Lakera GuardPrompts and responsesExternal serviceYou want a finished filter with no upkeep
The commercial platformAll of the above plus observationVendor serviceCompliance requirements and reporting

The first two rows do not compete but cover two different stages. The scanner works before deployment, on files. The filter works while the application runs, on content. Deploying only one leaves the other side open. On a new project, though, remember that the second row describes a closed project, so the filter role today falls to the third or fourth row of this table.

The last row deserves consideration when you need evidence rather than protection alone. Open tools produce no auditor reports, carry no console, and will not ensure anyone reviews events. Under formal requirements that is sometimes decisive regardless of detection quality.

Where to wire it in

Placement matters, and the most common mistake is wiring it where half the traffic does not pass anyway.

Model scanning belongs in the build pipeline and at the moment of download. A model pulled by hand onto a developer's workstation bypasses both, so it pays to have one command the team actually runs, written into the project's setup instructions.

Content filtering belongs at three points: user input, content fetched externally, and model output. The third gets skipped most often, and without it an injection that arrived through a fetched document goes straight to the user.

For personal data detection, consider a dedicated tool such as Presidio if that is your main problem. The filtering library handles it in passing, while a specialised tool gives more control over data types and country specific rules.

The last item is a model registry. Knowing which model, at which version, pulled from where, runs in production is the precondition for reacting to any advisory about a vulnerable artefact. Without that registry, "does this affect us" can only be answered by guessing.

Common mistakes

The first is loading models from public repositories without a scan. An organisation name is not verification, and a file in an executable format runs code on load.

The second is treating a clean scan as a guarantee. The scanner detects known patterns, so it sieves out what is known rather than confirming a file is safe.

The third is skipping conversion to the safe format even though it is available. One off work removes an entire class of risk, and yet the old format stays out of habit.

The fourth is enabling every check in the filtering library at once. Latency climbs while most of them do not apply to your case, so you pay response time for protection you do not need.

The fifth is filtering input alone. A model's response is sometimes the only place where it shows that something went wrong earlier.

The sixth is confusing the open tools with the commercial platform. Material describing a console, reports, and runtime observation concerns the paid product rather than what installs with one command.

FAQ

Does Protect AI still exist?

Not as a separate company. Palo Alto Networks announced the acquisition in April 2025 and closed it on the twenty second of July that year, and the commercial products now operate as part of the Prisma AIRS platform.

Are the open tools still free?

Yes, both stayed free: the model artefact scanner under Apache 2.0, the library filtering prompts and responses under MIT. Both install through an ordinary package manager, with no account and no key. Development is where they differ: the scanner shipped a release in February 2026, while the filtering library was archived in July 2026 and is no longer maintained.

Why would loading a model file be dangerous?

Because in the popular format a file holds instructions for reconstructing an object, the ability to call any function included. Loading executes those instructions, so a crafted file runs code on your machine while the model itself behaves normally.

Does the safe tensor format solve the problem completely?

It solves code execution on load, since it stores numbers alone. It does not protect against a model trained to misbehave in selected situations, and that is a separate risk category requiring behavioural testing.

How does the filtering library differ from external services?

In where it runs. The library works inside your process, so content never leaves your infrastructure and the cost is processor time. An external service updates detection itself and loads none of your machines, while prompts pass through somebody else's server.

The scanner's code sits in its GitHub repository, and the acquisition details in the Palo Alto Networks announcement.