HOL Guard 2.1: 51,000 Test Cases, HMAC-Backed Reconnect, and a New Command Classification Engine
HOL Guard 2.1 ships a 51,000-case command classification corpus, HMAC-backed dashboard reconnect, signed Codex hook manifests, DNS-pinned archive downloads, and a typed GitHub capability model — all open source, canary-tested on TestPyPI.
The Release
HOL Guard 2.1 changes 575 files, adds 107,000 lines, and ships a 51,000-case command classification corpus that assigns every AI-generated shell command a security floor before the tool runs it. Every layer of the stack changed — the local daemon, the Codex hook pipeline, the dashboard UI, CI, the test harness.
Three things define this release:
- A six-level action lattice (allow, warn, review, require-reapproval, sandbox-required, block) backed by a 51,000-case decision-diff corpus. Zero known gaps. Zero lowered decisions. The corpus ships with the code.
- HMAC-backed dashboard reconnect that survives daemon restarts without dropping the trust relationship between the dashboard and its local server. Mutual challenge-response with replay protection.
- Codex hook manifest signing that cryptographically binds hook identity so a compromised workspace cannot silently swap which hooks Guard trusts.
Behind those headlines: restricted archive downloads with DNS pinning, structured GitHub command capability modeling across shell/REST/GraphQL, cross-platform CI (Linux, macOS, Windows), a dashboard migration from npm to bun, and a TestPyPI canary pipeline that verifies installed-origin proof before any stable tag.
Command Classification: 51,000 Cases, Six Floors
Guard 2.1 replaces the previous allow/block binary with a six-floor action lattice. Every tool invocation gets exactly one floor. No configuration file can lower it.
- allow — safe, no interaction
- warn — notify but proceed
- review — surface in the approval center
- require-reapproval — block until developer approves in the dashboard
- sandbox-required — isolate before touching the host
- block — refuse execution
The corpus lives in tests/fixtures/guard-command-corpus/. Each of the 51,000 cases maps a command to its expected floor. CI runs a decision-diff report against every case on every push. A merge always requires review. A credential read always requires reapproval. A Guard configuration modification always blocks.
Classification rules sit in command_critical_floors.py (490 lines): merge, release, history, delete, secret, access, workflow, content, and dynamic mutations each get a fixed floor.
Dashboard Reconnect: HMAC Challenge-Response
Guard's dashboard connects to a local daemon over localhost. When the daemon restarts — after an update, a crash, a reboot — the old connection model had no way to confirm it was talking to the same installation.
The 2.1 protocol (dashboard_reconnect.py, 416 lines):
POST /v1/update/reconnect/prepare— the dashboard asks the current daemon for a signed authorization. The daemon persists areconnect_id, installation fingerprint, and HMAC-bound challenge to Guard's home directory.- The daemon restarts. The dashboard probes candidate ports until it finds a
/healthzendpoint. POST /v1/update/reconnect/challenge— the dashboard challenges the recovered daemon. The daemon checks that the authorization is still fresh, then returns a server-side HMAC proof.- The dashboard verifies the server proof, then sends
POST /v1/update/reconnect/verifywith its own client proof. The daemon checks the replay cache. - Only after mutual verification does the dashboard resume status polling.
Every challenge binds to a specific installation ID, guard home ID, and compatibility version. Replays fail. Cross-installation challenges fail. Port mismatches fail. The dashboard test suite backs this with 302 lines of security-specific e2e tests (guard-update-reconnect-security.test.ts).
Hook Manifest Integrity and Archive Safety
Codex hooks intercept tool calls inside the developer's own process. Before 2.1, hook configuration lived in plain workspace files — an attacker with filesystem access could modify the identity record and redirect Guard's inspection pipeline.
Guard 2.1 introduces signed hook manifests (codex_hook_manifest.py, 495 lines). Each manifest carries the hook's identity, expected payload shape, and an HMAC signature from a private key stored in Guard's home directory — outside the workspace, with restrictive permissions and atomic writes. Guard verifies the signature at load time. A failed check logs a tamper event and refuses the hook.
Archive safety follows the same trust-nothing principle. Agents download archives frequently — model weights, package tarballs, training data. 2.1 routes every archive download through a five-module pipeline that enforces HTTPS-only transfers, DNS pinning, redirect limits (max 3, same-origin after the first), and bounded streaming with a size cap — then scans the result in a sandbox with no network access and dropped capabilities before the host filesystem ever sees it. Incomplete downloads land in temp; only verified completes get an atomic rename into the workspace.
GitHub Capability Modeling
gh pr merge, gh release create, gh secret set — GitHub CLI commands are among the most common things an AI agent runs and among the riskiest. Before 2.1, Guard pattern-matched against command strings. A reformulated command could slip past.
2.1 ships a typed capability model spanning six modules:
- github_capability_contract.py (313 lines) — maps every GitHub operation to its required capability and security floor
- github_rest_capabilities.py (304 lines) — REST API path classification
- github_graphql_capabilities.py — GraphQL operation classification
- github_shell_capabilities.py (497 lines) and github_shell_bindings.py (489 lines) — shell binding model mapping
ghcommands, flags, and arguments to capabilities - github_command_capabilities.py — unified classification entry point
- verified_github_reads.py (362 lines) — proven-read pattern allowing safe
ghreads through--jsonformatters
gh repo delete is blocked regardless of spelling. gh pr view --json number,title is allowed. gh issue create requires review. Classification follows what the command does — not what it looks like.
CI, Canary Pipeline, Dashboard
Guard's build and release infrastructure grew substantially in 2.1:
- Cross-platform CI across Linux, macOS, and Windows (Python 3.10–3.13). uv 0.9.26 pinned with its SHA-256 in the CycloneDX SBOM.
- TestPyPI canary pipeline (
publish.yml, now ~930 lines): every release-branch push produces a unique per-PR canary wheel, verifies byte equality against the build artifact, installs on a clean environment, runs the full 51K-case corpus, and proves installed origin on all three OS targets. - Dashboard migrated from npm to bun 1.3.14. Four new Playwright e2e specs cover reconnect, command activity, approval scope, and protection health — all targeting the installed wheel, not a dev checkout.
- Command activity API (
command_activity_api.py, 474 lines) with privacy controls, authenticated totals, filters, detail views, and execution-proof copy.
Installing It
The 2.1 alpha ships to TestPyPI for canary testing. Stable releases, Docker images, and Homebrew updates follow.
pip install --index-url https://test.pypi.org/simple/ hol-guardThe repository is github.com/hashgraph-online/hol-guard. Apache 2.0.
Continue reading
All posts
MCP Tool Poisoning: How the AI Agent Protocol Became a Supply Chain Attack Surface
The MCP protocol connects AI agents to over 10,000 tools. It also creates a new supply chain attack surface: poisoned tool descriptions that silently hijack agent behavior. Here's the data, the CVEs, and what to do.

Slopsquatting: When AI Hallucinations Become Supply Chain Attacks
AI coding assistants hallucinate package names 19.7% of the time. Attackers register those names on npm and PyPI before real packages can claim them. Tens of thousands of developers have already installed malicious packages their AI suggested. Here is how the attack works, what the research shows, and how to stop your team from becoming the next victim.

Prompt Injection Defense in 2026: What Actually Works When Detection Is Impossible
OpenAI says perfect prompt injection detection is still unsolved. Three academic proofs show why it may never be possible. This is the defense-in-depth architecture that actually works in 2026.
