Seal
Online
- File
- qwen2.5-0.5b-instruct-q4_k_m.gguf
- Commit
- 9217f5db
- Signed
- cosign
Pinned Hugging Face commit
Zarf moves the boxes. airlock proves the model inside is safe, genuine and unchanged.
A Go CLI that seals an AI model online and checks it again on the offline side, before it runs in an air-gapped network.
Online
Pinned Hugging Face commit
Air gap
Same bytes on both sides
Offline
Checked with no network
PassedOnline · airlock seal
Air gap · Zarf or USB
Offline · airlock verify
| Command | Where | What it does |
|---|---|---|
airlock seal | Online | Checks formats and provenance, then signs a manifest. |
airlock verify | Offline | Checks signature and every file with no network, writes a report. |
airlock smoke | Offline | Asks the running model server a question with a known answer. |
airlock check | Anywhere | Runs only the format checks. |
airlock zarf | Online | Writes a Zarf package that runs verify during deploy. |
Build it, seal a model, verify it, then test the running server. Tested end to end with Qwen2.5 0.5B Instruct (Q4_K_M, commit 9217f5db).
go build -o airlock .
cosign generate-key-pair
airlock seal ./bundle --key cosign.key --hf Qwen/Qwen2.5-0.5B-Instruct-GGUF --rev <40-char commit>
airlock verify ./bundle --key cosign.pub
llama-server -m bundle/qwen2.5-0.5b-instruct-q4_k_m.gguf --port 8080 --offline
airlock smoke --url http://127.0.0.1:8080
Each car on this siding was turned back. The message under it is the one airlock prints.
Formats that can run code when loaded never get sealed.
"pytorch_model.bin": pickle-based format refused: it can execute code when loaded; convert to safetensors or GGUF RefusedA bundle signed by any key the offline host does not hold.
invalid signature (wrong key or tampered) RefusedEvery file must match the pinned upstream commit. Branch names are refused because they can move.
"model.gguf": sha256 differs from upstream RefusedThe demo's poisoned copy tells users to pipe a script into sudo sh. One changed byte after sealing, and the hash no longer matches.
Sealed74a4da8c9fdb
Found64a4dcef1b89
Zarf's signature proves the package is the one the packager built. It does not prove what went into it. A model swapped before packaging passes Zarf's checks.
airlock runs as a deploy step inside the package. It checks the model against its own seal, made earlier from the real files, so the swap is refused and the model server never starts.
Always sign the package and deploy with --verify=always. Tested with Zarf v1.0.0.
airlock zarf ./bundle --key cosign.pub
zarf package create . -o out --signing-key cosign.key
zarf package deploy out/zarf-package-airlock-model-*.tar.zst --key /etc/airlock/cosign.pub --verify=always
What airlock does not cover, so you can plan for it.