Safeguard
Product•

Scan Models From Hugging Face, Kaggle, ModelScope and Civitai

Scan models from every hub the same way: list sources, pin versions, check hashes and inspect files statically before loading. A practical multi-hub guide.

Safeguard Security Team
39 min read

Your teams pull model files from Hugging Face, Kaggle Models, ModelScope and Civitai, and each hub names, versions, hashes and licenses a model in its own way. To scan all of them to one standard, list every source in use, pin each model to an exact version, check every file against the hash the hub publishes (or record your own where it publishes none), and inspect each file statically for unsafe serialization and embedded code before anything loads it. Then rescan on a schedule, because the copy on the hub can change after you approved it.

This guide is for the AppSec lead or ML platform engineer who has just learned that "we only use Hugging Face" stopped being true some time ago. The first two thirds work with whatever tools you already have. Safeguard enters at "How Safeguard does this".

Key takeaways

  • A model file is code you did not write. Python's own documentation says pickle data can be built to run arbitrary code while it is being loaded, and PyTorch's torch.load warns never to load data from an untrusted source.
  • One hub is a review. Several hubs are a program: each has a different version unit, a different hash story, a different licence field and a different credential, so a single intake record has to normalise them.
  • Pin every model to an immutable version (a Hugging Face commit, a Kaggle variation version, a ModelScope commit, a Civitai model version), and verify file hashes before load.
  • Static inspection reads a file without executing it. It catches unsafe formats and embedded code paths; it does not prove a model is free of backdoors or bias, which OWASP's LLM supply chain entry says plainly.
  • Safeguard connects to all four hubs through its Hugging Face, Kaggle Models, ModelScope and Civitai integrations (GA). Each connection is read only, scans the files of the models you select for unsafe serialization formats and embedded code with AI-SPM model file scanning (GA), and records each model in your AI inventory through AI-BOM discovery (GA), with its licence or permissions.
  • Rescans run on a schedule under Integrations > Scheduled, or by hand from the project. None of the four integrations uses webhooks.
  • Policies and gates (GA) act with Block, Warn and Notify, and approvals run through exceptions.
  • Model weights and files are read for the scan and not stored, and the docs for each integration state that no customer data from it is sent to third-party LLMs.

The situation

The ticket usually starts small. A data scientist wants a text-to-image LoRA from Civitai for a marketing prototype. Another team fine-tunes a Gemma variation they found on Kaggle Models. A partner team in another region standardised on ModelScope because that is where their base models live. Meanwhile the main product still pulls a dozen checkpoints from the Hugging Face Hub, some pinned, some tracking main.

Your existing review covers Hugging Face, maybe. It might be a checklist, a scan in CI, or a habit of telling people to prefer safetensors. None of it was written with Kaggle variations, ModelScope commits or Civitai model versions in mind, and nobody has a single list of which models from which hub sit in which project.

A bad week looks like this. A model file loaded in a notebook turns out to be a pickle that imports something it should not. Nobody can say which projects pulled that model, which version they pulled, or whether the copy in the cache matches the copy on the hub. Legal asks whether the Civitai checkpoint allows commercial use, and the answer lives on a web page nobody saved. The fix itself is easy. Finding everything is the slow part.

The goal of this guide is to make that week boring: one intake standard for every hub, one inventory, one rescan rhythm.

Why models from several hubs are harder to secure than one

Every hub hosts the same broad kinds of files (PyTorch checkpoints, safetensors, GGUF, ONNX and framework-specific formats), so the file risk is the same everywhere. What differs is the metadata you need to make a decision and repeat it later. Safeguard's integration docs for each hub describe these differences in detail, and they are worth knowing whether or not you use Safeguard.

QuestionHugging Face HubKaggle ModelsModelScopeCivitai
What identifies a modelOwner and model name, with refs and revisionsOwner, model, framework and variation (for example google/gemma/transformers/2b)Owner and model name on modelscope.cnA numeric model id, with numbered model versions
What "a version" meansA git revision or commit on a branch or tagThe current version of a variationThe newest commit of the master branchThe newest published model version
Does the API publish a file hashRevisions and file listings are readable through the Hub APINo file hash; the download carries an MD5 or CRC32C from Kaggle's storageSHA-256 per file in the file listSHA-256 per file in the version's file list
Where licence terms liveModel card and repository metadataA licence per model versionA licence field per modelNo licence id; per-model permissions (commercial use, derivatives, credit), plus the base model's own licence
Read credentialUser access token, fine-grained recommendedKaggle API token, or a legacy username:keySDK token at read levelPersonal API key, scoped to the whole account
Private or gated contentPrivate and gated repositories the token can readPrivate models of the token's own account; some models require accepting terms firstPrivate and gated models, after accepting termsDownloads that need a signed-in account

Three practical consequences follow.

First, "pin the model" means four different things. On Hugging Face you pin a commit hash. On Kaggle you pin a variation and its version number. On ModelScope you pin a commit, and Safeguard's docs note that ModelScope documents no branch-to-commit lookup, so any tool has to infer the commit from the file list. On Civitai you pin a model version id, not the model id, because the model id points at whatever the newest version is.

Second, hash verification is uneven. ModelScope and Civitai publish a SHA-256 per file, so you can check a download against the hub. Kaggle's API publishes no file hash, so the best you can do is check the size Kaggle lists and the checksum its storage returns, then record your own SHA-256 at the moment of approval and treat that as the reference from then on.

Third, licence answers come in different shapes. A Kaggle or ModelScope licence field gives you an identifier to check. A Civitai model gives you a set of permissions and a base model, and the base model's licence also applies. If your intake form has a single "licence" box, the Civitai answer will not fit in it.

What the rules and references say

This is not legal or audit advice. It is a reading of the primary texts that shape a model intake process, so you can cite them in your own policy.

The format warnings come from the projects themselves

The Python documentation for the pickle module carries a warning box: the module is not secure, and it is possible to construct pickle data that executes arbitrary code during unpickling. It tells readers never to unpickle data that could have come from an untrusted source.

PyTorch's documentation for torch.load repeats the point: it "uses an unpickler under the hood" and you should never load data from an untrusted source. The current signature shows weights_only=True as the default, which restricts what the unpickler will accept. That default helps, but it applies only to code paths that call torch.load directly, and only to the PyTorch version you run.

The Hugging Face Hub documentation on pickle scanning explains why: a pickle can import modules and call builtins as it loads, and constructors run when objects are rebuilt. It suggests loading models from users and organizations you trust, relying on signed commits, or using formats that avoid pickle.

Safetensors was built as the answer to that problem. Its documentation describes it as a simple format for storing tensors safely, as opposed to pickle, and still fast through zero-copy loading. GGUF, documented on the Hub, is a binary format designed for fast loading with GGML-based runtimes, and models trained in PyTorch are often converted to it for local inference.

OWASP names the model supply chain as its own risk

The OWASP Top 10 for LLM Applications 2025 lists Supply Chain as LLM03. Its "Vulnerable Pre-Trained Model" item is the honest framing every model program needs: models are binary black boxes, and OWASP says static inspection "can offer little to security assurances" about hidden behaviour such as backdoors or bias. The same entry calls out licence risk and outdated or deprecated models.

Read that as a scope statement, not a reason to skip scanning. Static inspection is how you catch the file-level problems (unsafe formats, embedded code, tampered files). Behavioural assurance needs evaluation, red teaming and provenance, which are separate jobs.

NIST SP 800-218A extends secure development to AI models

NIST SP 800-218A, published in July 2024 by NIST with a CISA co-author, augments the Secure Software Development Framework (SSDF) version 1.1 with practices, tasks and notes specific to AI model development. If your organisation already maps its development process to the SSDF, 800-218A is where you extend that mapping to the models you train, fine-tune and consume. Third-party models arriving from public hubs fall naturally under the same expectations you apply to third-party code: know where it came from, verify it, and keep a record.

NIST AI RMF frames the risk program around it

The NIST AI Risk Management Framework (AI RMF 1.0) is the US reference for organising AI risk work. NIST's page notes that AI RMF 1.0 is being revised under the White House AI Action Plan, so cite it by version and check for the revision before you quote it in a policy. A model intake process is one of the concrete controls that sits under its governance and mapping functions.

Inventories: SBOM guidance and ML-BOM formats

CISA's SBOM page now leads with the 2026 update to the Minimum Elements for a Software Bill of Materials, which replaces the older 2021 baseline. If a model ships inside your product, your inventory practice should be able to say which model, from where, at which version.

CycloneDX supports a Machine Learning Bill of Materials (ML-BOM), which gives you a standard shape for recording models, datasets and their provenance alongside ordinary components. You do not need to adopt it on day one, but designing your intake record so it maps onto an ML-BOM later saves rework.

Hub-side scanning is helpful and limited

The Hugging Face Hub runs its own scanning on files pushed to repositories, triggered at each commit, and shows badges on files. Read that as a useful signal from one hub, not a control you own. It does not cover the other hubs, it does not know which revision your build pulled, and it does not record anything in your inventory. Several related posts go deeper on what a clean hub badge does and does not mean (see securing Hugging Face models).

Step by step, with or without Safeguard

These steps work with a shell, a spreadsheet and the hubs' own tools. Do them in order; each one depends on the one before.

1. Find every model source in use

You cannot scan what you do not know about. Search code, notebooks, Dockerfiles and CI files for the calls and URLs each hub uses. A starting set of patterns:

# Run from the root of each repository. Adjust the patterns to your code.
rg -n --hidden \
  -e 'from_pretrained\(' \
  -e 'hf_hub_download|snapshot_download' \
  -e 'huggingface\.co/' \
  -e 'kagglehub|kaggle\.com/models/' \
  -e 'modelscope' \
  -e 'civitai\.com/(api|models)' \
  .

Then search for model files that are already committed or cached:

find . -type f \( -name '*.bin' -o -name '*.pt' -o -name '*.pth' -o -name '*.ckpt' \
  -o -name '*.pkl' -o -name '*.safetensors' -o -name '*.gguf' -o -name '*.onnx' \) \
  -not -path './node_modules/*'

Neither command proves absence. They give you a first list to confirm with each team. Our post on finding model files in repos and artifact stores covers caches, buckets and container layers in more depth.

2. Record each model in one intake format

Put every model, from every hub, into the same record. A template that fits all four:

# model-intake.yaml (one entry per model you use)
- name: sentiment-base
  hub: huggingface            # huggingface | kaggle | modelscope | civitai
  locator: OWNER/MODEL        # Kaggle: OWNER/MODEL/FRAMEWORK/VARIATION ; Civitai: model id
  pinned_version: COMMIT_SHA  # HF commit, Kaggle version number, ModelScope commit, Civitai model version id
  files:
    - path: model.safetensors
      sha256: RECORDED_SHA256
      hub_published_hash: yes # yes for ModelScope and Civitai; no for Kaggle
  format_summary: safetensors # pickle-based | safetensors | gguf | onnx | mixed
  licence: apache-2.0         # Civitai: record permissions and base model instead
  civitai_permissions: null   # commercial_use, derivatives, credit
  base_model: null            # required for Civitai entries
  used_by: [project-a, inference-service]
  approved_by: NAME
  approved_on: 2026-10-25
  rescan: weekly

The fields that matter most are pinned_version, files[].sha256 and used_by. With those three, the bad week above turns into a query.

3. Pin to an immutable version

Use each hub's own version unit:

  • Hugging Face. Pass a commit hash as the revision when you download, not a branch name. A branch such as main moves when the owner pushes.
  • Kaggle Models. Record the full variation path (owner, model, framework, variation) and the version number you approved.
  • ModelScope. Record the commit you approved. Because ModelScope documents no branch-to-commit lookup, keep the file list and SHA-256 values with the commit so you can tell later whether a branch still points at the same content.
  • Civitai. Record the model version id. The model id alone means "whatever is newest".

4. Verify file hashes before anything loads

Compute a SHA-256 for every downloaded file and compare it with the hub's published value where one exists:

sha256sum model.safetensors
# compare the output with the SHA-256 the hub lists for that file and version

For Kaggle, which publishes no file hash, check the file size Kaggle lists, then record your own SHA-256 at approval. From then on, your recorded hash is the reference, and any later download that differs is a change you did not approve.

5. Inspect files statically, before loading

Static inspection means reading the file's structure without executing it. For pickle-based files, Python ships a disassembler in the standard library that prints the opcodes without running them:

# A plain pickle file
python3 -m pickletools suspicious.pkl | head -50

# A PyTorch .pt or .pth file is usually a zip; list it first, then disassemble the pickle entry
unzip -l model.pt
unzip -p model.pt '*/data.pkl' | python3 -m pickletools - | head -50

What you look for in the output: GLOBAL or STACK_GLOBAL opcodes that import anything beyond the tensor-rebuilding helpers a checkpoint normally needs (torch._utils, collections.OrderedDict, storage types). Imports of os, subprocess, builtins, posix or networking modules in a weights file are a stop sign. This manual check is good for spot reviews; it does not scale to every file in every version from every hub, which is where an automated scanner earns its place.

For safetensors, GGUF and ONNX, the risk profile is different. Safetensors stores a JSON header and raw tensor bytes, with no code path on load. GGUF and ONNX are structured binary formats; check that the file parses as the format it claims to be, and watch for repositories that ship a safetensors file alongside a pickle-based file that your loader might pick first. Our comparison of safetensors, pickle and GGUF has the full table.

6. Prefer safe formats and safe loaders

Where you control the loader, prefer safetensors, and keep weights_only=True on torch.load calls. Where a model only exists as a pickle-based checkpoint, convert it once in an isolated environment with no credentials and no network, record the hash of the converted file, and use that from then on.

File type you receivedMain riskWhat to do
Pickle-based checkpoint (.bin, .pt, .pth, .ckpt, .pkl)Code can run during loadInspect statically, load only with weights_only=True, convert to safetensors in isolation
SafetensorsLow format risk; tampering and licence still matterVerify hash, record licence, pin version
GGUFParser bugs in runtimes; tamperingVerify hash, keep the runtime patched, pin version
ONNXCustom operators and runtime bugsVerify hash, restrict custom ops, keep the runtime patched
Repository mixes safe and pickle-based filesLoader may pick the unsafe fileDownload only the files you approved; check which file the loader actually opens

7. Give each hub a least-privilege, read-only credential

Any scanner or mirror you run needs a credential per hub. Keep each one read only and scoped as tightly as the hub allows:

HubCredentialTightest scope availableNotes
Hugging FaceUser access tokenFine-grained, read access to selected repositories or one organizationHugging Face recommends fine-grained tokens for production; organizations can require approval
KaggleAPI token or legacy username:keyNo read-only option; create a key for this purpose aloneRevoke when you disconnect
ModelScopeSDK tokenRead levelWrite and admin levels exist; do not use them
CivitaiPersonal API keyWhole account; no narrower scopeCreate a key for this purpose alone; delete it when done

Rotate each credential on a fixed rhythm. Safeguard's docs recommend at least every 90 days for all four, and note that Hugging Face and Civitai credentials do not expire on their own.

8. Record licence or permissions, per version

Licence terms can change between versions. Record what applied to the version you approved. For Civitai, record the model's permissions (commercial use, derivatives, credit) and the base model, whose own licence also applies. A Civitai LoRA built on a base model with a restrictive licence carries that restriction.

9. Rescan on a schedule and on change

A model you approved last quarter can gain a new version, change its files on a branch you track, or be taken down. Rescan pinned versions on a schedule to confirm nothing changed, and scan new versions before anyone moves to them. Treat a hash mismatch on a pinned version as an incident until you understand it.

10. Decide what blocks and what warns

Write down, before the first finding arrives, which results stop a model from being used and which only raise a flag. A simple starting policy:

FindingAction
Pickle-based file imports modules outside the tensor-rebuilding setBlock until reviewed
File hash differs from the pinned or published valueBlock until explained
Pickle-based file with only expected importsWarn; plan conversion to safetensors
Licence or permissions unknown, or base model licence unknownWarn; route to legal
Model version no longer available on the hub (archived or taken down)Notify; plan a replacement

What to check per hub

Hugging Face Hub: refs, revisions and gated repositories

The Hub is git-backed, so revisions are commits and you can pin exactly. Private and gated repositories need a token that can read them, and organizations can require that tokens be approved by an admin or be fine-grained only. When a scan of a gated model fails with a 403, the cause is almost always the token's scope, its pending approval, or an organization that rejects classic read tokens. For revision pinning in depth, see verifying third-party model files before loading.

Kaggle Models: variations, versions and missing hashes

Kaggle organizes models as owner, model, framework and variation, and versions sit under the variation. Some models require the account to accept the model's terms before downloads work, so a scanner using your key will fail until that account has accepted them. Because the API publishes no file hash, record your own SHA-256 the first time you approve a version.

ModelScope: commits, file lists and pinning

ModelScope publishes a SHA-256 for every file in a model's file list, which makes download verification direct. It documents no branch-to-commit lookup, so pinning works by matching the newest commit named in the file list and confirming that the file list and hashes are unchanged. ModelScope's API also caps how many models per account and files per model it will list; any tool that walks the list needs to say when it hits that cap rather than silently stop. ModelScope also runs its own file check, and a file can be listed before that check finishes.

Civitai: model versions, permissions and mature content

Civitai hosts checkpoints, LoRAs and embeddings, and versions are first-class. It publishes a SHA-256 per file and per-model permissions rather than a licence id. Many Civitai pages carry sample images, some rated mature. A security review needs the files and the permissions, not the images, and a scanner that fetches only text and model files keeps image content out of your tooling entirely. Civitai can also archive or take down a model, after which its files are no longer served.

How Safeguard does this

Safeguard connects to the Hugging Face Hub, Kaggle Models, ModelScope and Civitai through four integration cards (GA). Every one of them is read only, scans the files of the models you select with AI-SPM model file scanning (GA), and records each model in your AI inventory through AI-BOM discovery (GA). The flow below is built from Safeguard's integration docs for each card.

  1. Open Integrations and find the card. The Hugging Face card sits under Integrations on the Project/Product tab. The Kaggle Models, ModelScope and Civitai cards sit under Integrations in the AI models group. The docs note that these three are switched on per workspace; if you do not see a card, ask your Safeguard contact to enable it.

  2. Choose Public or Private. Each card offers two modes. Public takes a model URL and needs no credential. Private takes a Name and a credential, and lists what that credential can read.

    HubPublic: what you pastePrivate: what you pastePrivate: what you can select
    Hugging FaceA model URL on huggingface.coA user access token (fine-grained recommended)Your models and your organizations' models, plus any added by URL, including private and gated models the token can read
    Kaggle ModelsA model variation URL on kaggle.com/modelsA Kaggle API token, or a legacy username:keyEvery variation of your account's models, private ones included, plus any added by URL
    ModelScopeA model URL on modelscope.cnAn SDK token (read level is enough)Your account's models, private and gated included, plus any added by URL
    CivitaiA model URL on civitai.comA personal API keyEvery model your account published, plus any added by URL, including downloads that need a signed-in account
  3. Create the credential with the least access the hub allows. The docs walk through each one:

    • Hugging Face: Settings > Access Tokens > New token, choose Fine-grained, name it, and grant read access to the repositories or organization to scan. Add read access to gated repositories only if you need them. The token starts with hf_.
    • Kaggle: Settings from your profile picture, then create an API token under API (or a legacy key, which downloads kaggle.json; join its username and key as username:key).
    • ModelScope: open your account's Access Token page and create a token with read access.
    • Civitai: Account settings, then API Keys, add a key named Safeguard, and copy it (Civitai shows it once).
  4. Optionally check the credential first with the hub's own tool. The docs give these checks, which run against the hub, not against Safeguard. We have not run them for this post; they are reproduced as the docs show them.

    # Hugging Face (the Hugging Face CLI has no command that creates a token)
    hf auth login --token "$HF_TOKEN"
    hf auth whoami
    
    # Kaggle
    export KAGGLE_API_TOKEN="<your token>"
    kaggle models list --owner "<your username>"
    
    # ModelScope
    modelscope login --token "$MODELSCOPE_API_TOKEN"
    
    # Civitai
    curl -H "Authorization: Bearer $CIVITAI_TOKEN" https://civitai.com/api/v1/me
    
  5. Connect and select. For Public, enter a Name, paste the URL, click Add, then Next. For Private, enter a Name, paste the credential into Access Token and verify it. Then click Next, select the models (Hugging Face models and revisions, Kaggle variations, ModelScope models, Civitai models), review and connect.

  6. Safeguard downloads and checks each file, then scans it. What happens per hub, as the docs describe it:

    • Hugging Face. Safeguard reads refs and revisions, downloads the files of each selected model at the selected revision, and scans them for issues such as unsafe serialization formats and embedded code.
    • Kaggle Models. Each variation is scanned at its current version. Because Kaggle's API publishes no file hash, Safeguard checks each file against the size Kaggle lists and the MD5 (or CRC32C) that Kaggle's storage returns with the download, and records the file's SHA-256.
    • ModelScope. Each model is scanned at the newest commit of its master branch. Safeguard checks each file against the SHA-256 ModelScope publishes. A branch is pinned to the newest commit its file list names, and only when that commit lists the same files with the same SHA-256.
    • Civitai. Each model is scanned at its newest published version, and each file is checked against the SHA-256 Civitai publishes.

    On every hub, the scan itself is static: AI-SPM reads the model files and looks for unsafe serialization formats and embedded code. It does not execute the model.

  7. Each model lands in the AI inventory, with its terms. The scan results and an AI inventory entry are stored per model. Kaggle and ModelScope entries carry the model's licence. Civitai entries carry the model's own permissions as Civitai publishes them (commercial uses allowed, derivatives, credit) and name the base model, whose own licence also applies, because Civitai publishes no licence id.

  8. Civitai stays text only. Safeguard reads text only from Civitai. No Civitai image or avatar is fetched or shown, and a model Civitai rates as mature is listed as text with a "mature content (text only)" marker. That keeps image content out of your security tooling without hiding the model from your inventory.

  9. Rescan on a schedule or by hand. None of the four integrations uses webhooks. Each selected model is scanned when you connect it. To pick up new revisions, versions or commits, set a schedule under Integrations > Scheduled, or rescan by hand from the project.

  10. Act on results with policies and gates. Policies and gates (GA) are where Safeguard enforces decisions, with three actions: Block, Warn and Notify. Approval for anything a gate stops runs through exceptions, so a team that needs something through can request it and leave a record. The integration docs for these four hubs describe scanning and inventory, not gate wiring, so check how model scan findings show up in your policy screens before you rely on a Block, and use the decision table from step 10 above as the starting rule set.

  11. Rotate and disconnect cleanly. To rotate, create or refresh the credential on the hub, find the connection under Project Configurations, choose Update, paste the new credential and save, then delete the old one on the hub. To disconnect, choose Delete from the connection's menu under Project Configurations, confirm, then delete or revoke the credential on the hub.

What Safeguard reads and stores

ReadStoredNot stored
Hugging FaceAccount name, model names, refs and revisions, files of selected modelsConnection settings, scan results, AI inventory entries, the token (encrypted at rest, never shown again)Model weights
Kaggle ModelsUsername, models and variations, each version's licence and file list, files of selected variationsConnection settings, scan results, AI inventory entries, the token (encrypted at rest)Model files, which are read for the scan and removed
ModelScopeUsername, model names, licences and visibility, each file list with SHA-256, files of selected modelsConnection settings, scan results, AI inventory entries, the token (encrypted at rest)Model files, read for the scan and removed
CivitaiUsername, model names, types, base models, ratings and permissions, each version's file list with SHA-256, files of selected modelsConnection settings, scan results, AI inventory entries, the key (encrypted at rest)Model files, and anything from Civitai's images

The docs for each of the four integrations also state that no customer data from it is sent to third-party LLMs.

What each integration never needs

The docs list the access Safeguard never asks for, which is useful when your identity team reviews the request:

  • Hugging Face: write access, inference or billing permissions, organization admin rights, or access to datasets and Spaces.
  • Kaggle: write access, competition or dataset publishing rights, or another person's credentials.
  • ModelScope: write or admin access, Studio or deployment access, or another person's token.
  • Civitai: Buzz or generation access, or the right to post, comment or upload. Civitai OAuth app credentials do not work; Safeguard uses a personal API key.

Troubleshooting the common failures

What you seeHubLikely causeFix
A gated or organization model fails with 403Hugging FaceToken lacks read access, is pending approval, or the org requires fine-grained tokensGrant read access, wait for approval, or use a fine-grained token
Model is private. Authentication required.Hugging FacePrivate model added on the Public tabUse the Private tab with a token
A scan fails with a gated or 403 errorKaggleThe model's licence has not been accepted on KaggleAccept the terms with the token's account, then rescan
This is not a Kaggle model URLKaggleURL is not a model variation pageUse the full owner, model, framework and variation URL
A scan says ModelScope is still checking a fileModelScopeModelScope's own file check is not finishedRescan later
A scan fails with a file hash mismatchModelScope, CivitaiThe download did not match the published SHA-256Rescan; if it repeats on ModelScope the model changed mid-download, on Civitai report the model to Civitai
Civitai has archived this model (or taken it down)CivitaiCivitai moderated the model and no longer serves its filesNothing to scan; remove it from the connection

What Safeguard does not do

  • It does not prove a model is safe to use. AI-SPM model file scanning is static. It reads files and flags unsafe serialization formats and embedded code; it does not run the model, and it cannot detect backdoors, poisoned training data, bias or harmful outputs. OWASP is clear that static inspection offers little assurance about those. Evaluation and red teaming remain your job.
  • It does not write to any hub. Every integration is read only. It will not open a discussion, file a report, push a fix, edit a model card or convert a checkpoint for you. Reporting a bad model to the hub, and converting pickle-based files to safetensors, stay with your team.
  • It does not watch hubs in real time. None of the four integrations uses webhooks. New versions are picked up when a scheduled rescan runs or when someone rescans by hand. Set a schedule that matches how fast your teams adopt new versions.
  • It does not scan Hugging Face datasets or Spaces through this card, and it does not need access to them. If your risk includes datasets or Spaces, handle them separately.
  • It does not see models it is not told about. A model downloaded in a notebook from a hub URL nobody added to a connection is not in the inventory. Step 1 of this guide (finding every source) still matters.
  • It does not decide licence questions. It records the licence, or on Civitai the permissions and base model, as the hub publishes them. Whether a use is allowed is a legal decision.
  • It does not narrow credentials the hub cannot narrow. Kaggle offers no read-only key and Civitai keys cover the whole account. Safeguard only reads, but the key you hand over can do more; create one for this purpose alone and revoke it when you disconnect.
  • It does not lift hub-side limits. ModelScope's API caps how many models and files it lists; past that cap Safeguard says so rather than cutting the list silently, and you add the rest by URL.

Common mistakes

  • Pinning the model, not the version. A Civitai model id, a Kaggle model without a variation version, or a Hugging Face main branch all move. Pin the version unit each hub uses.
  • Treating a hub badge as your control. A clean badge on one hub says nothing about the other hubs, the revision your build pulled, or the copy in your cache.
  • Scanning once at intake and never again. Files under a tracked branch can change. Pinned versions can be taken down. Schedule rescans.
  • Using a write token "because it was there". Every hub here works with read access, and Kaggle and Civitai keys already reach further than you would like. Do not add write scope on top.
  • One licence box for every hub. Civitai permissions and base model licences do not fit a single licence id. Record both.
  • Converting checkpoints on a developer laptop. Converting a pickle-based file means loading it. Do it in an isolated, credential-free environment, then pin the converted file's hash.
  • Forgetting the loader. A repository with both a safetensors file and a pickle-based file may load the pickle if your code asks for it. Check which file is actually opened.
  • Letting the inventory drift from the code. If a project stops using a model, remove it from the connection. If a new one appears, add it before it ships.

FAQ

How do I scan a Hugging Face model before downloading it?

Pin a commit, list its files, and scan those files in an environment where nothing loads them. With Safeguard, add the model URL on the Hugging Face card's Public tab, or connect a fine-grained read token on the Private tab, select the model and revision, and connect. Safeguard downloads and scans the files and records the model in your AI inventory.

Can Safeguard scan Kaggle Models?

Yes. The Kaggle Models integration (GA) scans each selected model variation at its current version and records it with its licence. It works with a Kaggle API token or a legacy username:key, and public variations can be added by URL with no credential. The card is switched on per workspace.

Does Safeguard support ModelScope?

Yes. The ModelScope integration (GA) scans each model at the newest commit of its master branch, checks every file against the SHA-256 ModelScope publishes, and records the model and its licence in your AI inventory. A read-level SDK token is all it needs for private models.

Can I scan Civitai checkpoints and LoRAs without pulling images into my tools?

Yes. The Civitai integration reads text only. No Civitai image or avatar is fetched or shown, and models Civitai rates as mature appear as text with a "mature content (text only)" marker. Model files are checked against Civitai's SHA-256 and scanned, then removed.

Is a safetensors file always safe to load?

The format has no code path on load, which removes the main pickle risk. It does not tell you whether the weights were tampered with, whether the licence allows your use, or whether the repository also ships a pickle-based file your loader might pick. Verify the hash and the file your code actually opens.

Does Hugging Face's own scanning mean I can skip mine?

No. Hub-side scanning is a useful signal for one hub at the time of each commit. It does not cover Kaggle, ModelScope or Civitai, does not know which revision your build pulled, and does not maintain your inventory.

How often should I rescan models from public hubs?

Match your adoption rate. If teams move to new versions weekly, rescan weekly. In Safeguard, set a schedule under Integrations > Scheduled, or rescan by hand from the project; there are no webhooks.

Does Safeguard store our model weights?

No. Model files are read for the scan and not kept. Safeguard stores the connection settings, the scan results, the AI inventory entry for each scanned model and the credential, which is encrypted at rest and never shown again.

What permissions does the Hugging Face token need?

Read access to the repositories or organization you want scanned, ideally as a fine-grained token. Add read access to public gated repositories only if you need them. Safeguard never needs write, inference, billing, webhook or discussion permissions.

Is model file scanning enough for an AI supply chain program?

No. It covers the file layer. You still need inventory of where models are used, version pinning, licence review, evaluation of model behaviour, and patching of the libraries and runtimes that load models.

Model files are one layer of the AI supply chain; the Python frameworks, tokenizers and serving runtimes that load them are ordinary open source dependencies with ordinary CVEs. The section below covers how Safeguard closes the fix gap for those dependencies and the container images you build around your models.

Fix it without waiting for upstream

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation categories include dependencies, licenses, security posture and findings, and each one is set separately. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds.

3. Gold Registry: start from components that are already fixed

Gold Registry provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs and a completed license check, with signed build provenance (signed with Safeguard's key and verifiable with cosign, SLSA Build Level 3 as the design target) and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. Ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingSafeguard policies and gates in CI
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

None of these demos shows the model hub integrations themselves. They show the surfaces your team would use around them: asking questions of your Safeguard data from Claude, fixing a vulnerable dependency from the terminal, and scanning from your own machine.

The first demo connects Claude to the Safeguard MCP server (GA) with OAuth and shows how you choose which tools Claude can use. Once your model scans and inventory are in Safeguard, the same connection is how an engineer can ask about findings from inside Claude.

Click through it at your own pace, or open it full screen.

The second demo is a real session with the Safeguard CLI (GA). It installs the CLI, opens the interactive terminal with safeguard, and asks it to fix the lodash CVE in a repository. The CLI reads the finding and advisory, asks before any command that changes something, edits package.json to lodash 4.17.21, runs npm install and npm test with approval, prints a summary and pushes nothing. The same loop applies to the Python libraries that load your models.

Click through it at your own pace, or open it full screen.

The third demo sets up the local runner (GA) on your own machine, approves it with its device code, and scans from the terminal. Teams that keep model code and conversion scripts on internal machines can scan that code without moving it.

Click through it at your own pace, or open it full screen.

Quick check

Why can a Kaggle model not be verified against a hub-published hash the way a ModelScope or Civitai model can?

Kaggle's API publishes no file hash. The best available check is the file size Kaggle lists plus the checksum its storage returns with the download, after which you record your own SHA-256 as the reference. Safeguard does exactly that and records the SHA-256 of each file.

A Civitai LoRA allows commercial use. Is that the whole licence answer?

No. Civitai publishes per-model permissions rather than a licence id, and the base model the LoRA was built on has its own licence, which also applies. Record both.

Sources

Related reading: securing Hugging Face models, verifying third-party model files before loading, finding model files in repos and artifact stores, safetensors vs pickle vs GGUF and AI-SPM, AI Gateway and AI-BOM.

To try it, download Safeguard at safeguard.sh/download and read the setup guides at docs.safeguard.sh/docs.

Last reviewed: 25 October 2026. Product capabilities change; check docs.safeguard.sh for the current state.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.