Review local-model safety checks
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,::1orlocalhost), and refuses one that also answers on the node's network address: bind it to127.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/pushand/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_versionraises 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 thestart:program (following its links, asuv tool installandpipxmake them), or fromenvironment:for a server it does not start (on a Mac). - It never starts LM Studio (
kind: lmstudiowithstart:is refused), and starts mlx-lm withHF_HUB_OFFLINE=1, so that a call naming another model cannot make it download one. Its proxy refuses, with400 oz0_local_field, a call to an mlx server whose body namesadapters,draft_modelornum_draft_tokens, and a call to LM Studio whose body namesdraft_model, which would make the server load weights nobody pinned. It also refuses an mlx start command with--draft-modelor--adapter-path. - Its proxy routes a call by its body's
modelfield, the one the servers read, and refuses with400 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 asha256: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. 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:
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.