Observed since 21 Oct, 11:21 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
A password-protected CLI for managing an allowlist of approved AI model signatures
A password-protected CLI for managing an allowlist of approved AI model signatures.
Prevent unauthorized AI models from running on your infrastructure. Only models in your approved database can execute. Every action is logged for compliance.
When you deploy AI locally, you face a trust problem:
AI Model Guard solves this with cryptographic signature verification and a local allowlist.
# Install from PyPI
pip install aimodelguard
# Get the path to the bundled operations handbook (PDF)
aimodelguard handbook
# Initialize the database (one-time)
aimodelguard init
# Approve a model
aimodelguard approve --model ./qwen-1.5b.gguf --publisher "Qwen Team" --use-case "extraction"
# Verify a model before running
aimodelguard verify --model ./qwen-1.5b.gguf
The full reference documentation is shipped as a PDF alongside the code on PyPI. After pip install aimodelguard, run:
aimodelguard handbook
# prints the path to the bundled PDF, e.g.:
# /usr/local/share/doc/aimodelguard/AIModelGuard-Handbook.pdf
The PDF is 14 pages, ~870 KB, and covers everything in this README plus the threat model, security architecture, integration patterns, and troubleshooting.
DOI: 10.5281/zenodo.21578648 (cites the whole project: code + handbook)
For load-time checks in Python applications, use the library:
import aimodelguard
result = aimodelguard.verify("/var/models/qwen.gguf")
if not result.approved:
raise RuntimeError(f"Model denied: {result.reason}")
# result.approved -> bool
# result.reason -> "approved" | "not_in_database" | "quarantined" | ...
# result.sha256_hash -> str | None
# result.publisher -> str | None
# result.use_cases -> list[str] | None
# bool(result) -> same as result.approved
# Optional: load with llama-cpp-python after verifying
from aimodelguard.integrations.llama_cpp import Llama
llm = Llama(model_path="/var/models/qwen.gguf", n_ctx=2048)
The library accepts the same password sources as the CLI: the password= argument, the MODELGUARD_PASSWORD env var, or an interactive click.prompt fallback.
aimodelguard init — Initialize the databaseaimodelguard approve --model PATH — Approve a modelaimodelguard verify --model PATH — Verify a model is approvedaimodelguard list — List all approved modelsaimodelguard remove --hash HASH — Remove an approvalaimodelguard quarantine --model PATH — Quarantine a modelaimodelguard backup create — Create a manual backupaimodelguard backup list — List all backupsaimodelguard backup restore PATH — Restore from a backupaimodelguard backup verify — Verify all backupsaimodelguard audit — View the audit logZero external dependencies at runtime — AI Model Guard does not phone home, does not require an internet connection, and does not depend on any third-party service. The database, the hashes, and the audit log all live on your filesystem. The CLI is fully usable on an air-gapped machine.
Hash-only verification — AI Model Guard verifies cryptographic hashes (SHA-256) of model files. It does not parse model formats, does not load model weights, and does not care about file contents beyond the bytes that get hashed. This makes it format-agnostic (works with GGUF, safetensors, PyTorch, ONNX, anything else) and means a "fake" test model with random bytes is just as valid a test case as a real 7B parameter network.
Fail closed — If AI Model Guard can't verify a model (file missing, hash mismatch, expired approval, quarantined, database locked, etc.), the default behavior is to block the load. The verifier is meant to be a hard gate, not a soft suggestion.
Local-first is a feature, not a limitation — The lack of cloud sync, central management, or real-time publisher verification is a deliberate design choice. AI Model Guard's threat model is "an attacker swaps a model file on your disk" — defending against that does not require a network. If you need publisher signature verification, transparency logs, or centralized approval workflows, layer those on top of AI Model Guard; don't replace it.
Simple and audit-compliant, not fool-proof — AI Model Guard is meant to be a small, well-understood tool that you can read end-to-end, audit, and trust. The design intentionally avoids features that add complexity without a proportional security benefit: no two-person approval workflow, no transparency log, no TPM binding, no keyserver, no revocation service, no DRM. If a security team needs those, they should use a heavier tool — AI Model Guard's job is to catch the common case (file substitution) and provide a clean audit trail.
✅ Supply chain attacks — Tampered models are rejected ✅ Insider threats — Unauthorized models are blocked ✅ Compromised models — Can be quarantined immediately ✅ Misuse — Use case restrictions prevent off-label use ✅ Compliance violations — Full audit trail
❌ Initial model trust — The first time you approve a model, you trust the publisher ❌ Zero-day vulnerabilities — AI Model Guard can't detect unknown backdoors ❌ Bypass attacks — Determined attackers could modify AI Model Guard itself ❌ Password compromise — If the master password is stolen, all bets are off
Apache 2.0
Gerald Enrique Nelson Mc Kenzie
10.5281/zenodo.21578648
0.2.0 (final — no further versions planned)
Every AI Model Guard command (except init) requires the master password. AI Model Guard provides three ways to provide it, in priority order:
MODELGUARD_PASSWORD environment variable (recommended for scripts/CI)# Linux / macOS
export MODELGUARD_PASSWORD="mySecret123"
aimodelguard init --db-path ./db.sqlite
aimodelguard approve --model ./qwen-1.5b.gguf
# Windows PowerShell
$env:MODELGUARD_PASSWORD = "mySecret123"
python -m aimodelguard.cli init --db-path .\db.sqlite
# Windows cmd.exe
set MODELGUARD_PASSWORD=mySecret123
python -m aimodelguard.cli init --db-path .\db.sqlite
If the env var is set, the CLI uses it and never prompts. This is the recommended way to use AI Model Guard in automation, CI pipelines, and shell scripts.
If MODELGUARD_PASSWORD is not set, the CLI prompts for the password with hidden input (no echo to terminal).
aimodelguard init --db-path ./db.sqlite
# Enter master password: ********
# Confirm master password: ********
The prompt uses click.prompt(hide_input=True), which correctly handles TTY detection on Linux, macOS, and Windows.
init requires confirmationThe init command asks for the password twice (with confirmation) to prevent typos. All other commands only ask once.
AI Model Guard ships with a pytest test suite covering both unit-level logic and end-to-end CLI workflows.
# Install with test dependencies
pip install -e ".[test]"
# Run all tests
pytest tests/ -v
# Run only the unit tests (fast)
pytest tests/test_basic.py -v
# Run only the CLI workflow tests (slower, exercises the full CLI)
pytest tests/test_cli_workflow.py -v
The CLI workflow test (tests/test_cli_workflow.py) sets a hardcoded master password so the test can run non-interactively:
test_password_123subprocess.run(...) call inside the test that invokes a password-protected commandgetpass via stdin without a human typing itrun_modelguard() helper feeds "test_password_123\n" as input_textThis password is only used inside the test suite and never appears in production code paths. When you run the CLI manually, you choose your own password during aimodelguard init.
How the test provides the password: the test's run_modelguard() helper sets MODELGUARD_PASSWORD=test_password_123 in the subprocess environment, which the CLI picks up and uses instead of prompting. (Previously the test piped the password via stdin, but click.prompt(hide_input=True) doesn't read from non-TTY stdin, so we switched to the env var.)
tests/test_basic.py — 6 unit tests:
test_compute_file_hash — SHA-256 hashing works on real filestest_database_init_and_approve — DB init, password setup, model approvaltest_backup_and_restore — Backup creation, listing, restorationtest_quarantine — Quarantine blocks verificationtest_audit_log — Every action is logged with timestamptest_password_verification — Wrong password is rejected (with Windows file-lock safe cleanup)tests/test_cli_workflow.py — 1 end-to-end test (21 scenarios):
If you want to drive the CLI yourself:
# 1. Initialize (you'll be asked for a password)
aimodelguard init --db-path ./test.sqlite
# 2. Create a dummy model
dd if=/dev/urandom of=mymodel.gguf bs=1M count=10 # Linux/macOS
# or
fsutil file createnew mymodel.gguf 10485760 # Windows
# 3. Approve it (enter the same password)
aimodelguard approve --db-path ./test.sqlite --model ./mymodel.gguf
# 4. Verify
aimodelguard verify --db-path ./test.sqlite --model ./mymodel.gguf
# 5. List
aimodelguard list --db-path ./test.sqlite
# 6. Cleanup
rm -rf ./test.sqlite ./backups/
Note on Windows: if aimodelguard is not on your PATH after pip install -e ., use python -m aimodelguard.cli ... instead. The tests use this form for cross-platform compatibility.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.2.0 | 26 Jul 2026 | 6 |
This describes our collected data; it is not a security assessment.
Observed since 21 Oct, 11:21 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:750c581f8171e7f1db178496debc393412724edcba12b17b0e353f6c5db21a4d