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.
Contents
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-guard
The repository is github.com/hashgraph-online/hol-guard. Apache 2.0.
Continue reading
All posts
BREAKING: CVE-2026-18432 - Frontend Admin WordPress Unauthenticated Admin Takeover
CVE-2026-18432 is a CVSS 9.8 privilege-escalation flaw in Frontend Admin by DynamiApps that can let unauthenticated attackers reset the default WordPress administrator account. Update to 3.29.10.

BREAKING: CVE-2026-74764 - Pandora TAR Path Traversal Enables Arbitrary File Write
CVE-2026-74764 is a CVSS 10.0 path traversal in Pandora TAR extraction that lets untrusted archives write outside the analysis directory. v1.12.5 is affected; deploy the upstream fix.

BREAKING: CVE-2026-73043 - SiYuan Template Calculation RCE in Desktop Client
CVE-2026-73043 is a critical SiYuan flaw where unsanitized database Template calculation output reaches Electron innerHTML and can become OS command execution. Upgrade to 3.7.4 or later.
