ModelScan vs Fickling: when each one fits
A team that downloads or receives pre-trained model files has to decide which checks run before a file is loaded. ModelScan fits a multi-format scan gate in CI and pipelines, and Fickling fits a load-time allowlist hook in front of pickle loading. The two tools answer different questions. ModelScan asks whether a file contains unsafe code across many formats before it moves forward. Fickling asks whether each pickle load touches only imports on a list the team has approved, and it raises an error when it does not.
Three questions decide between them. The first is where the check must sit. ModelScan's README recommends scanning before loading pre-trained models, after training and before deployment, which suits a gate that rejects artifacts before they reach a registry or serving path. Fickling's allowlist hook runs at the moment of loading, which suits code paths where a file could reach torch.load without passing through a pipeline step. The second is which formats the team handles. ModelScan covers PyTorch (Pickle), TensorFlow SavedModel and Protocol Buffer, Keras H5 and Keras V3, and classic ML formats saved with Pickle, Cloudpickle, Dill and Joblib. Fickling's documented coverage centers on plain pickles and PyTorch formats, including TorchScript and the PyTorch ZIP archive.
The third question is licensing. ModelScan is Apache-2.0 licensed, which most enterprise legal reviews accept without extra conditions. Fickling is licensed under LGPL-3.0, so confirm with counsel how your organization treats weak copyleft before embedding it in internal tooling or a distributed product. Whichever tool you choose, confirm current versions and Python support against your own environment, since ModelScan 0.8.8 supports Python 3.10 up to but not including 3.13 and Fickling 0.1.12 requires Python 3.10 or newer.
Which scanner fits which scenario
This table walks through illustrative scenarios and names the better starting point for each, based on formats, whether the check runs before a load or inside a pipeline, and the kind of output the team needs. Read it as a starting point for your own model intake policy, since neither tool covers every threat and some scenarios call for both.
| Scenario (illustrative) | Better fit | Why |
|---|---|---|
| Platform team scanning every model before it enters a registry | ModelScan | ModelScan covers PyTorch Pickle, TensorFlow SavedModel, Keras H5 and V3, and Pickle, Cloudpickle, Dill and Joblib files in one CLI run. It ranks findings by severity and returns nonzero exit codes, which suits a pipeline gate across mixed formats. |
| ML engineer loading one pickled checkpoint with torch.load | Fickling | Fickling can hook Python's pickle module so each load is checked against an allowlist of imports, raising UnsafeFileError on failure. This places the check at load time, directly in front of torch.load. |
| Team with Keras and TensorFlow model files | ModelScan | ModelScan lists Keras H5, Keras V3 and TensorFlow SavedModel among its supported formats. Fickling's listed coverage centers on pickle and PyTorch formats, so confirm its fit for Keras artifacts before relying on it. |
| Security analyst who must inspect pickle opcodes by hand | Fickling | Fickling decompiles and symbolically executes pickles without running them, so an analyst can read the reconstructed logic. ModelScan reports byte-signature findings and does not give a decompiled view of the file. |
| Team that needs a verdict on a file from an external source before any tooling touches it | Fickling | Both tools analyze without executing embedded code. Fickling's decompilation helps an analyst explain why a file is suspicious, while ModelScan's severity labels suit triage queues. Confirm the workflow your analysts need before choosing. |
| Compliance lead who needs a documented scan step for model intake | ModelScan | ModelScan's README recommends scanning before loading pre-trained models, after training and before deployment, which maps to a documented intake checkpoint. Confirm with your assessor which evidence format they expect from the scan output. |
| Team relying on Hugging Face Hub checks alone | Neither as a replacement | Hugging Face runs its own pickle import scan and ClamAV on pushed files and says the scan is not foolproof. Local scanning with either tool adds a check you control, but neither tool covers every threat. |
| Team with a strict copyleft review policy on dependencies | ModelScan | ModelScan is Apache-2.0, while Fickling is LGPL-3.0. Legal review decides whether LGPL linking is acceptable for your build, so confirm it with counsel before adding Fickling to a product pipeline. |
How ModelScan and Fickling read pickle files differently
ModelScan and Fickling both look inside serialized model files without trusting them, but they answer different questions. The cards below cover how each reads a file, how each fits a pipeline or a load path, and who ends up owning the rules and the findings.
Byte-level signature reading
ModelScan reads model files byte by byte and looks for unsafe code signatures instead of loading them, so embedded code never runs. Because it matches patterns, its coverage is only as good as its signature set for the formats you handle. Ask the maintainers how signatures are added and tested, and run it against a file you know is malicious before you rely on it for a given format.
Symbolic execution for analysis
Fickling decompiles and statically analyzes pickles by symbolically executing them, so analysis does not run the file. This gives an analyst the reconstructed logic of a pickle, which is useful when a finding needs explaining. The cost is that someone must read that output, so plan for a reviewer with pickle and Python expertise rather than a pass or fail gate alone.
Allowlist hook at load time
Fickling can hook Python's pickle module so every load is checked against an allowlist of imports from ML libraries considered safe. A failed check raises UnsafeFileError, which stops the load inside your process. The allowlist is a policy decision: your team or a platform owner must decide which imports are acceptable, and must update that list when a legitimate model needs a new one.
CLI exit codes and Python API
ModelScan ranks findings as CRITICAL, HIGH, MEDIUM or LOW and offers a CLI with nonzero exit codes plus a Python API, so a scan can gate a CI/CD stage or a model registry import. Decide which severities block a pipeline and who may approve an exception. Fickling is used as a library or CLI, so the gating logic is usually something your team writes around its output.
Bytecode rewriting and test injection
Fickling can rewrite pickle bytecode and inject code into pickles for testing. For a security team, this is how to produce known-bad samples that check whether your scanners and load-time hooks actually fire. Hugging Face's Pickle Scanning documentation uses Fickling in the same way to show how code can be inserted. Keep these generated samples in a controlled test corpus, never in a production model store.
Who owns rules and findings
With ModelScan, the signature set and severity model come from the project, and your team owns the pipeline gate and exception process. With Fickling, your team owns the allowlist and the review of anything it flags. Name one owner for each list before rollout, and confirm the review path for disputed findings with your own security and ML teams.
Capabilities side by side from supplied facts
This table compares ModelScan and Fickling on formats, check placement, analysis method, output, CI fit, license and Python support, using only confirmed facts. Read each row against your own loading path: if models are pulled into a pipeline before use, the scanner fit differs from a check that runs inside every load call.
| Capability | ModelScan | Fickling |
|---|---|---|
| Model formats | PyTorch Pickle, TensorFlow SavedModel and Protocol Buffer, Keras H5 and Keras V3, and classic ML formats saved with Pickle, Cloudpickle, Dill and Joblib | Plain pickles, PyTorch formats including TorchScript versions and the PyTorch ZIP model archive |
| Check placement | Pipeline scan run before loading, after training and before deployment, as the README recommends | Pickle module hook that checks every load against an import allowlist, or analysis run as a library or CLI |
| Analysis method | Reads model files byte by byte for unsafe code signatures without loading them | Symbolically executes pickles so analysis does not run them, and can decompile and rewrite bytecode |
| Severity output | Ranks findings as CRITICAL, HIGH, MEDIUM or LOW | Raises UnsafeFileError when an allowlist check fails; confirm with the vendor whether it grades findings by severity |
| CI integration | CLI with nonzero exit codes and a Python API for CI/CD pipelines | Python library and CLI; confirm with the vendor how exit codes and reports are produced for pipeline use |
| License | Apache-2.0 | LGPL-3.0; confirm with your legal team what the LGPL terms require when you embed or modify the library |
| Python support | Version 0.8.8 supports Python 3.10 up to but not including 3.13 | Version 0.1.12 requires Python 3.10 or newer |
What the licenses and editions mean for each tool
ModelScan is released under the Apache-2.0 license by Protect AI. Apache-2.0 permits internal use, modification and redistribution, and it includes an express patent grant. Your obligations center on keeping license notices and attribution intact when you ship the code. A platform team can fork the scanner, add internal signatures or wrap it in a gateway without the copyleft duties that apply to some other licenses. Protect AI also sells a commercial product in the same space, so the open-source project and the vendor's offer are separate decisions.
- Apache-2.0 terms: Internal modification and bundling into an internal image carry notice and attribution duties, but they do not require you to publish your own pipeline code.
- Guardian as a separate offer: Protect AI describes Guardian as its enterprise model scanning product with newer scanners, broader model support and enforcement for Hugging Face models. Do not assume the open-source release has the same coverage.
- Inspiration credit: The ModelScan README states that the project was heavily inspired by Matthieu Maitre's picklescan. That credit does not make the two tools interchangeable, so test both on your own model set.
- Support terms: The supplied facts do not describe a paid support tier for the open-source project. Ask Protect AI whether support exists for the open-source release and what it covers.
Before approving ModelScan, confirm with Protect AI which Guardian capabilities you need and whether any of them require a commercial license, so the procurement record reflects what you will actually run.
Fickling is licensed under LGPL-3.0 and developed by Trail of Bits. LGPL is a weak copyleft license. When you distribute a modified version of Fickling itself, you generally must make that modified library available under LGPL terms. Code that only uses the library follows different rules depending on how it links to Fickling and how you ship it. The result depends on your packaging, so the license review should start from your deployment plan rather than from the license name alone.
- Internal modification: Running a patched Fickling inside your own environment, without distributing it outside the organization, generally carries fewer obligations than shipping it. Ask counsel how your internal use counts.
- Redistribution in images or tooling: If you bundle Fickling into a container, an internal package or a vendor appliance, the LGPL notice and source availability duties for the Fickling portion may apply. Plan a notice file and a method for supplying the library source for each version you ship.
- Library use versus embedding: Calling Fickling from your own loader is a different case from embedding its hook into a product you sell. Write down which pattern you use.
- Paid editions: The supplied facts do not document any paid edition of Fickling. Confirm with the Trail of Bits maintainers whether commercial support, an enterprise distribution or contractual terms exist before you assume they do not.
Ask counsel to review the LGPL-3.0 obligations against your packaging plan, and get the commercial support answer from the maintainers in writing.
Both tools are open source, but adoption still needs a written record of the license, the support path and the exact versions you approved. This tab turns the license and edition questions into items for the procurement and security review. It does not restate license text, and it leaves the legal conclusions to counsel.
- License record: Store the license file and the exact version you tested. The supplied facts name ModelScan 0.8.8, released on February 18, 2026, and Fickling 0.1.12, released on June 26, 2026, so record whichever version you pin.
- Python constraints: ModelScan 0.8.8 supports Python 3.10 up to but not including 3.13. Fickling requires Python 3.10 or newer. Confirm that your runtime fits both before you schedule the pilot.
- Support path: Ask each vendor who handles security fixes, how reports are received and what response you can expect in writing. Do not assume a commercial contract exists for either tool.
- Maintainer changes: Check the license and maintainer in each new release. A later release can change terms, so the approval should name the version and the date it was reviewed.
File the answers with the license decision so the approval covers the versions you actually deploy, and repeat the review when you upgrade either tool.
What drives the running cost of each scanner
The largest cost in either tool is engineering time, and most of it is one-time setup. For ModelScan, that means wiring the CLI into a CI job so a nonzero exit code blocks a pipeline, and deciding which severities fail the build. For Fickling, it means placing the UnsafeFileError hook where every torch.load call in your code path passes through it, then writing the allowlist. Neither tool's fixed setup cost is published, so ask your implementation partner to estimate both from your pipeline layout and the number of model loading paths. A written quote should itemize these tasks separately so you can see which one dominates.
Recurring work is where the two tools diverge. A Fickling allowlist is a list of ML library imports you have judged safe, so every new library, new model architecture or new PyTorch release that introduces an import outside that list will fail a load until someone reviews it. Someone on your team owns that review queue. ModelScan's recurring cost is mostly triage: each CRITICAL or HIGH finding needs an analyst to confirm whether it is a true unsafe payload or a false positive, and to record the decision. Both tools also pin you to Python versions. Fickling 0.1.12 requires Python 3.10 or newer, and ModelScan 0.8.8 supports Python 3.10 up to but not including 3.13, so a Python upgrade on your base image may force a scanner upgrade or a rebuild.
Every upgrade of either scanner should trigger re-validation. Run your known-good and known-bad test models through the new version before it reaches production, and confirm the allowlist still behaves as expected. If your team pursues Protect AI's Guardian, which the ModelScan README describes as its enterprise scanning product, add the subscription cost, its licensing terms and any integration work to the recurring line. Ask any quote to state who maintains the allowlist, who performs triage, how upgrades are tested and whether Guardian is in or out of scope.
Moving from one scanner to the other without a gap in coverage
This sequence lets a team add Fickling beside ModelScan, or replace one with the other, while every model file keeps passing through a check at each load point. The output is a tested gate, a reconciled set of findings and a written record of what changed.
Inventory model formats and load points
The platform or ML engineering lead lists every model format the organization accepts, such as PyTorch pickle, TorchScript, PyTorch ZIP archives, Keras H5, Keras V3, TensorFlow SavedModel, and classic pickle, cloudpickle, dill or joblib files. For each format, record where it is loaded, including notebooks, training jobs, inference services and any direct calls to torch.load. Done means a table that maps every format to its load points and to the check that currently covers it, with uncovered formats marked clearly.
Keep the existing gate running
Leave the current scanner in every CI job and load path unchanged while the new tool is evaluated. Do not remove or relax any rule during the transition. Done means the current pipeline runs green on the same inputs as before, and the team has a recorded baseline of its current findings and exit codes to compare against later.
Install the second tool in a parallel job
The engineer adds Fickling, or ModelScan if it is the newcomer, as a separate, non-blocking CI job that scans the same artifacts. Confirm the runtime first: ModelScan 0.8.8 supports Python 3.10 up to but not including 3.13, and Fickling 0.1.12 requires Python 3.10 or newer. Done means the parallel job runs on the same Python version as the production gate and produces output for every format in the inventory.
Reconcile findings on a known sample set
Build a sample set that includes files known to be safe, files with embedded code that the team has already identified, and at least one example from each format in the inventory. Run both tools on every file and tabulate results side by side, noting where one flags a file the other passes. Investigate each disagreement by hand. Done means a written reconciliation that explains every mismatch, and a decision on whether each format is covered by a check that is acceptable to the security team.
Update exit-code handling and the allowlist
The engineer maps each tool's result to the pipeline's pass or fail behavior. ModelScan reports findings as CRITICAL, HIGH, MEDIUM or LOW and returns nonzero exit codes, so confirm which severities block a merge. Fickling's hook raises UnsafeFileError on a failed allowlist check, so the team decides which import allowlist entries apply to each library and records the reason for each one. Done means a reviewed configuration file with severity thresholds, exit-code mapping and allowlist entries, approved by the team that owns model intake.
Promote the new check to blocking
Once reconciliation is accepted, switch the new tool to a blocking gate in CI and add the load-time check in front of torch.load where Fickling's hook is used. Keep the old gate in place for one full release cycle as a fallback, then compare results from real intake. Done means that new merges and loads fail on the new check, and the team has seen at least one real intake pass through it without an unexplained result.
Retire the old check and document the change
Remove the superseded scanner from CI and load paths, and delete any allowlist entries or exemptions that existed only for it. Update the model intake procedure to name the surviving tools and their versions. Hugging Face notes that its own scan is not foolproof, so keep the procedure's wording clear that no single scanner is a complete control. Done means the repository contains a change record with the reconciliation results, the retired check and the owner of each remaining gate.
Carry forward policy and rebuild the rest
Policy, severity thresholds and the model inventory transfer directly, since they describe what the organization accepts rather than which tool checks it. CI jobs, allowlist entries and the license review are rebuilt: Fickling is LGPL-3.0 and ModelScan is Apache-2.0, so legal review should confirm how each is distributed and linked in your environment. Ask legal and procurement to confirm these terms before the new tool becomes blocking. Done means a signed-off list of transferred items and a separate list of rebuilt items with owners.
Where scanner implementations usually run long
Implementation work for either tool tends to stall in four places: Python environment alignment, ownership of allowlist and severity decisions, handling findings on legitimate files, and proving that the check runs before load. ModelScan 0.8.8 supports Python 3.10 up to but not including 3.13, and Fickling 0.1.12 requires Python 3.10 or newer, so confirm that your pinned interpreter satisfies both before you choose where each tool sits. If the same CI image also runs training or serving code on a newer interpreter, plan a separate scanning environment rather than discovering the conflict during a release.
Fickling's hook depends on an allowlist of imports, so someone must own that list. Decide who approves additions when a new model family introduces a class that is not yet trusted, who reviews a change to the list, and whether approvals are recorded in version control. ModelScan's severity ratings (CRITICAL, HIGH, MEDIUM and LOW) need the same kind of decision: which levels fail the pipeline, who may accept a finding, and how an exception expires. Confirm with each maintainer how their project expects these policies to be documented, and test the rules against a known-good model from your own registry.
Findings on legitimate files are the most common source of delay. A pickle that imports a utility from a trusted library can trigger a block, and each false positive needs a documented disposition rather than an ad hoc bypass. Ask whether your model types, including any custom Keras, Joblib or Dill artifacts, are covered by each tool at the depth you need. For auditors, record the scanner version, rule set and configuration, and capture a log showing that the scan or hook ran before torch.load or any deserialization call in the deployment path. Neither tool's supplied material is an attestation, so the evidence trail is your responsibility to design and test.
Questions teams ask before choosing a pickle scanner
Can ModelScan and Fickling run together in the same pipeline?
Yes, they can run together because they work at different points and answer different questions. ModelScan reads model files byte by byte for unsafe code signatures across several formats, including PyTorch pickles, TensorFlow SavedModel, Keras H5 and V3, and classic ML formats. Fickling symbolically analyzes pickles and can hook Python's pickle module so each torch.load call is checked against an import allowlist. A common layering is a ModelScan gate in CI and before deployment, with Fickling's allowlist applied where code loads model files. Confirm the exit behavior and the Python versions each tool supports in your own environment before you combine them in one job.
What can our own engineers do, and where does outside help add value?
Your engineers can install both tools, run them against a model registry, wire a nonzero exit code into CI and review findings. ModelScan's CLI and Python API are designed for this, and its README recommends scanning before loading pre-trained models, after training and before deployment. Outside help usually adds value in designing where the gates sit, writing the allowlist for your ML libraries, testing that a deliberately unsafe test file is blocked, and documenting the controls for an assessor. DeployOpen plans, implements, integrates and documents self-hosted platforms inside your infrastructure under a fixed-scope written agreement.
What drives the cost and effort of adding either scanner?
Cost comes from people time and the environment, not from either license, since both projects are open source. The main drivers are how many model sources you ingest, how many formats and Python versions your teams use, how many pipelines need a gate, and how much policy you need to write, such as which imports Fickling's allowlist permits. Ongoing effort recurs when you upgrade and retest after releases. Ask any partner for a quote that itemizes discovery, pipeline integration, allowlist design, testing, documentation and any retainer for upgrades.
Does Hugging Face's own scanning make a local scanner unnecessary?
No. Hugging Face scans every file pushed to the Hub with ClamAV and a pickle import scan that lists imports without executing them, but its own documentation says the scan is not foolproof. Files you download, copy from partners or receive from internal teams never pass through that scan again. A local gate lets you apply your own policy, record evidence and block a file before it reaches a training job or an inference service, so keep it even when you use the Hub.
Can Fickling's allowlist be enforced consistently across a team?
It can be enforced when the hook is installed in a shared, controlled place, such as a base image, a common library wrapper or a startup module that every training and serving job imports. Fickling's documentation describes hooking Python's pickle module to check every load against an allowlist and raising UnsafeFileError on failure. Individual developers who skip the import, or run code outside the shared image, bypass it. Treat the allowlist as code under review, test it against your library versions, and confirm the behavior with the Fickling maintainers for your Python version, since it requires Python 3.10 or newer.
What should our legal team confirm about LGPL-3.0 versus Apache-2.0?
Ask counsel to confirm how the LGPL-3.0 license of Fickling applies to your intended use, including whether you modify the library, bundle it into an internal image, or distribute it to customers or partners. ModelScan is Apache-2.0, which many organizations already review and accept. Licensing review also depends on whether you run the tools as internal CI utilities or ship them inside products. This page does not offer legal advice, so have counsel review the license text and your distribution model before standardizing on either tool.
How is a fixed-scope engagement from DeployOpen agreed before work starts?
Most DeployOpen engagements are fixed-scope, and the scope, deliverables and timelines are agreed in writing before any work begins. A quote follows from that written scope, because DeployOpen does not publish a price list. For a pickle scanning gate, the written scope would typically name the model sources and formats in use, the pipelines to integrate, the allowlist and policy work, the tests and the documentation to be delivered. Ask for the written scope, the deliverables and the acceptance criteria before you commit, and ask whether ongoing upgrades and retesting should be a separate retainer.
How DeployOpen helps choose, implement or migrate a model scanning gate
DeployOpen plans, implements and hardens self-hosted open-source platforms inside the client's own infrastructure, so a model scanning gate can be placed where your model files actually enter your environment. We help teams decide between a byte-signature scanner and a load-time allowlist, then build and document the gate that enforces the choice.
How we scope
- Written scope names the model formats, repositories and pipelines the gate must cover.
- We confirm whether checks run before loading, in CI/CD, or at both points.
- Scope records the license review for ModelScan (Apache-2.0) and Fickling (LGPL-3.0) against your policy.
- Engagements are fixed-scope, with deliverables and timelines agreed in writing before work starts.
How we build
- We wire the chosen scanner into your pipeline and fail builds on the severity levels you define.
- Where a load-time allowlist applies, we place the check in front of torch.load in your inference code.
- We test the gate against sample files you approve, including deliberately unsafe test files.
- Every configuration change is kept in version control so reviewers can trace what was enforced.
How we hand over
- You receive documentation of the scanning points, exit-code handling and known coverage limits.
- Runbooks explain how to triage findings, quarantine files and record decisions for auditors.
- We document which controls the gate supports as evidence, without claiming any audit outcome.
- Handover includes a walkthrough with the engineers who will maintain the scanner after go-live.
How we support
- Ongoing support, upgrades and continuous testing are available as retainers after handover.
- We track scanner releases and test upgrades against your pipeline before they reach production.
- Retainer scope, response expectations and fees are set in a written quote, not estimated here.
- Ask any provider to confirm how new model formats will be added to the gate and who owns that work.

