---
title: "Review local-model safety checks"
description: "Understand endpoint, model and weight checks before serving local models."
canonical_url: "https://docs.oz0.ai/fleet/local-models/trust"
---
# Review local-model safety checks

> Understand endpoint, model and weight checks before serving local models.

For: cluster operators.

Understand endpoint, model and weight checks before serving local models.

## What the node refuses

Local model servers are often reachable from the whole network without a key. The node keeps them off it:

- It uses only servers on loopback (`127.0.0.1`, `::1` or `localhost`), and refuses one that also answers on the node's network address: bind it to `127.0.0.1`.
- Its proxy passes only inference calls (`/v1/chat/completions`, `/v1/completions`, `/v1/embeddings`, `/v1/responses`, `/v1/messages`) and refuses model management such as Ollama's `/api/pull`, `/api/push` and `/api/create`.
- It refuses versions below a minimum that each advisory raises: Ollama 0.17.1 and newer (CVE-2026-7482), and for MLX an mlx 0.29.4 or newer (CVE-2025-62608 and CVE-2025-62609). `min_version` raises it further for one server, and refuses a server that does not say its version. An mlx server whose mlx the node cannot read is refused too: the node reads it from the environment of the `start:` program (following its links, as `uv tool install` and `pipx` make them), or from `environment:` for a server it does not start ([on a Mac](https://docs.oz0.ai/fleet/local-models-on-a-mac#serve-a-model-with-mlx-lm)).
- It never starts LM Studio (`kind: lmstudio` with `start:` is refused), and starts mlx-lm with `HF_HUB_OFFLINE=1`, so that a call naming another model cannot make it download one. Its proxy refuses, with `400 oz0_local_field`, a call to an mlx server whose body names `adapters`, `draft_model` or `num_draft_tokens`, and a call to LM Studio whose body names `draft_model`, which would make the server load weights nobody pinned. It also refuses an mlx start command with `--draft-model` or `--adapter-path`.
- Its proxy routes a call by its body's `model` field, the one the servers read, and refuses with `400 oz0_local_field`, for every kind, a body that is not one JSON object, that names a field twice, or that names the model under a second key in another case (`MODEL`, `Model`).
- It serves only models pinned under `models:` with a `sha256:` digest that the server confirms, and whose files are GGUF or safetensors where the server says. A model without a pin, a pin without a digest, a digest the server does not report and a digest that differs are all refused, and the reason names the models. It never starts a server with `--trust-remote-code`.

Only Ollama reports digests. For MLX the node hashes the model's folder itself, [as on a Mac](https://docs.oz0.ai/fleet/local-models-on-a-mac#pin-the-model). For vLLM, llama.cpp, LM Studio and other OpenAI-compatible servers, `allow_unpinned: true` on the server serves its models without a confirmed digest: the models in `models:` without a digest, or every model it lists when `models:` is empty. The node then logs a warning, and the server's reason on the Nodes page reads `serving without a pinned digest (allow_unpinned): ...`.

The node does not download model files: pull them with the server's own tools, then pin their digests.

### Pinned is not vetted

A digest pins a model's integrity: the node serves the bytes you pinned, nothing else. It says nothing about who made them or whether anyone looked: an edited model can be pinned exactly.

So a local model is unvetted until a tenant admin vets it, and a job that may run on it starts tainted (each call that can send data out waits for a person) and runs on a node with sandbox tier 1 only; it is never refused.

The node reports each served model's digest, and whether it confirmed it against a pin or serves it with `allow_unpinned`, in its heartbeats, so the server keeps the model's provenance:

```bash [Terminal]
oz0 model provenance local/qwen3-coder
oz0 model vet local/qwen3-coder --reason "model card and licence reviewed" --publisher Qwen --source hf:Qwen/Qwen3-Coder-8B
```

The vetting holds for the digest the nodes report when it is given (they must agree, or name one with `--digest`), and lapses while a node serves other weights under the name, such as after a re-pin. A model no node reports a digest of (a server under `allow_unpinned`, or none connected) is vetted only by its name, with `--by-name`, which covers any weights served under it. Vetting adds a person's judgement beside the digest; it never says a model is safe. See [Provenance and vetting](https://docs.oz0.ai/spend/models-and-keys/data-rules#provenance-and-vetting).


## Sitemap

See the full [sitemap](https://docs.oz0.ai/sitemap.md) for all pages.
