ZLAR is a deterministic execution governance layer for AI agents.
It intercepts agent tool calls, evaluates them against signed policy, routes decisions to humans when required, and produces cryptographic proof that governance happened. No AI in the enforcement path. The gate pattern-matches. It cannot be persuaded.
- A gate that sits between the agent and real-world actions
- Deterministic policy enforcement — regex matching, not reasoning
- Human-in-the-loop escalation via Telegram (approve/deny from your phone)
- Hash-chained, Ed25519-signed audit trail on every decision
- Governed Action Receipts — portable proof that an action was governed
- Framework-agnostic: Claude Code, Cursor, Windsurf, any MCP client
- Not a monitoring dashboard that watches after the fact
- Not an AI that judges whether an action "seems safe"
- Not a trust scoring system that builds a reputation for agents
- Not a sandbox — it governs the decision, not the execution environment
- Not tied to any model provider — the entity that sells agents cannot credibly govern them
git clone https://github.com/ZLAR-AI/ZLAR.git
cd ZLAR && bash install.shInstalls with deny-heavy defaults. Your agent is governed in under 60 seconds.
~/.zlar/bin/zlar doctor # verify everything works
~/.zlar/bin/zlar status # see what's governedAdd human approval via Telegram: ~/.zlar/bin/zlar telegram
Something not working? See Troubleshooting or run zlar doctor.
Agent issues tool call (shell command, file write, API request)
|
+-- Gate intercepts at execution boundary
|
+-- Loads Ed25519-signed policy (agents cannot modify their own rules)
|
+-- Evaluates: which rule matches?
| +-- allow -> tool executes, audit entry + receipt written
| +-- deny -> tool blocked, audit entry + receipt written
| +-- ask -> human notified via Telegram, action denied immediately
| +-- agent retries -> gate checks for human response
| +-- human approved -> executes on retry, receipt records "authorized by human"
| +-- human denied -> blocked on retry, receipt records "denied by human"
| +-- no response -> blocked (fail-closed, silence is not consent)
|
+-- Hash-chained audit entry records the decision
+-- Governed Action Receipt provides portable proof
Two enforcement surfaces share the same policy and audit trail:
- Bash gate (
bin/zlar-gate) — hooks into Claude Code, Cursor, Windsurf. Pure bash. Zero dependencies beyond jq and openssl. - MCP gate (
mcp-gate/gate.mjs) — TCP proxy between any MCP client and server. Interceptstools/callJSON-RPC messages. Per-entry Ed25519 signing, policy signature verification, standing approvals.
The agent does not volunteer to be governed. It is governed by architecture.
The receipt is the portable proof that a governed action was evaluated by deterministic policy and decided by the stated authority.
# Generate a receipt from an audit event
bin/zlar-receipt --last --key ~/.zlar-signing.key --pubkey ~/.zlar-signing.pub
# Verify it — anyone with the public key can do this
bin/zlar-verify receipt.json --pubkey key.pubVALID
Signature valid. Action "Bash" in domain "file" was deny by policy at 2026-04-05T21:00:00.000Z.
A receipt proves:
- A specific action was attempted by an AI agent
- Deterministic policy was evaluated against that action
- The decision was made by the stated authority (policy rule or human)
- The record has not been tampered with since creation
- The receipt is anchored to the audit hash chain
Receipts are cross-gate compatible — a bash-gate receipt verifies with the Node.js verifier and vice versa. The detail is hashed, not exposed — you can share a receipt with an auditor without revealing the command.
Every gate decision writes a hash-chained, Ed25519-signed audit entry:
{
"ts": "2026-04-05T09:14:22Z",
"agent_id": "claude-code",
"domain": "file",
"action": "git push origin main",
"outcome": "denied",
"rule": "R014",
"authorizer": "human:7662799203",
"prev_hash": "a1b2c3...",
"signature_algorithm": "Ed25519",
"signature": "mOiZF8E3MKFeyuRw..."
}authorizer: "human:7662799203"— a specific human made this decision. Non-repudiable.prev_hash— SHA-256 of the previous entry. Tamper with any record and every subsequent hash breaks.signature— Ed25519 over SHA-256 of the canonical entry. Every entry is individually signed.
This is not the agent's account of what it did. This is the infrastructure's record of what happened.
If the enforcement layer uses intelligence, the enforcement layer can be attacked with intelligence. If the enforcement layer is deterministic, the only attack is against the policy itself — which is a human artifact, signed with Ed25519, stored outside agent context. The absence of intelligence in the gate is the security property.
An enforcement layer that uses reasoning to evaluate actions can be subverted by reasoning-based attacks. The enforcement layer's capability becomes its vulnerability.
- Compromised signing key — an attacker with the key can sign a permissive policy. Mitigation: key never lives on the agent's machine. Rotation invalidates prior signatures.
- Compromised gate binary — if replaced, all enforcement is lost. Mitigation: R012 blocks agents from modifying their own governance. Host-level IDS is the defense layer below the gate.
- Actions the gate cannot see — channels that bypass the hook or proxy. The gate governs tool calls. OS-level containment governs everything else.
A security tool should state its own boundaries, not just its competitors' failures.
| Layer | Component | What it does |
|---|---|---|
| Enforcement | zlar-gate |
Policy engine. Intercepts tool calls, classifies, evaluates signed rules, writes audit trail and receipts. |
| Enforcement | mcp-gate |
TCP proxy for MCP. Same policy, same audit format, per-entry signing, standing approvals. |
| Evidence | lib/receipt.mjs |
Governed Action Receipt generation and verification. Cross-gate compatible. |
| Evidence | bin/zlar-verify |
Standalone receipt verifier. Anyone can verify with just the public key. |
| Observation | zlar-witness |
Sequence detection from audit trail. Detected, not enforced. |
| Observation | zlar-digest |
Governance summary. Decisions, latency, sequences, novelty. |
| Identity | zlar-agents |
Per-agent policy bindings, standing approvals, delegation depth limits. |
| Identity | Agent manifest | Capability boundary per agent. Narrows policy, never widens. (Invariants) |
| Policy | zlar-policy |
CLI for Ed25519-signed policy rules. Keygen, sign, verify. |
| Session | lib/session-state.sh |
Velocity, loop detection, denial bursts. Thin counters, not reasoning. |
| Human | lib/human-invariants.sh |
Protects the human: decision cap (H6), deliberation floor (H15), approval rate monitoring (H14), capacity tracking (H13), authenticity checks (H17). |
| Adapters | adapters/ |
Framework hooks for Claude Code, Cursor, Windsurf. |
The canonical entrypoint runs every test suite and prints the total assertion count. CI runs this on every push. It is the single source of truth for the "1000+ assertions" badge.
bash tests/count-assertions.sh # run all 28 files, print summary
bash tests/count-assertions.sh --detail # also show per-file pass counts
bash tests/count-assertions.sh --badge # print shields.io badge URLCurrent state (v2.7.1): 28 files, 1022 assertions, 0 failures.
The tests need bash, jq, and an OpenSSL with Ed25519 support (LibreSSL
on macOS does not qualify — use brew install openssl@3 and put it on PATH
first). node is optional — .mjs test files will be skipped gracefully if
node is not available. python3 is optional — canonicalization cross-check
will be skipped gracefully if python3 is not available.
# Core governance (bash)
bash tests/test-receipt.sh # Receipt generation and cross-gate verification
bash tests/test-manifest.sh # Manifest CLI and schema invariants
bash tests/test-agent-identity.sh # Agent identity, risk tiers, authorization levels
bash tests/test-human-invariants.sh # Human invariant enforcement (H6, H13, H14, H15, H17)
bash tests/test-perimeter-closure.sh # Policy rules, sandbox, path sanitization
bash tests/test-crypto.sh # Cryptographic abstraction layer
bash tests/test-session-state.sh # Session counters
bash tests/test-standing-approvals.sh # Standing approval matching
bash tests/test-approval-binding.sh # Approval binding (action fingerprint)
bash tests/test-inbox-hmac.sh # Inbox HMAC verification
bash tests/test-doctor.sh # Installation health checks
bash tests/test-policy-loading.sh # Policy load fail-closed corpus
bash tests/test-witness.sh # Sequence detection from audit
bash tests/test-canary.sh # Canary pending-file lifecycle
# Canonicalization (cross-language verification)
node tests/test-canonicalization.mjs # 62 vectors across Node and jq -S -c
python3 tests/verify-canonicalization.py # 28 vectors cross-checked in Python
# Receipt v1 envelope format and semantic validation
node tests/test-receipt-v1.mjs # v1 create/sign/verify/tamper/universal
node tests/test-semantic-validation.mjs # Layer 4: rule-outcome, authorizer, temporal, delegation
# MCP gate
node mcp-gate/test.mjs # Base gate tests
node mcp-gate/test-hardened.mjs # Policy verification, signing, fail-closed, standing approvals
node mcp-gate/test-receipt.mjs # Receipt generation, verification, delegation chains
node mcp-gate/test-cedar.mjs # Cedar P1/P2 rules, gate action mapping
# Cedar policy verification
node cedar-poc/test.mjs # Cedar base rules
node cedar-poc/test-e23.mjs # Cedar E-23 risk-tiered governance
# SDK layer
node sdk/daemon/test.mjs # Daemon lifecycle
node sdk/membrane/test.mjs # Membrane boundary enforcement
node sdk/authzen/test.mjs # AuthZen integration
node sdk/hook-adapter/test.mjs # Hook adapter HTTP surface| Dependency | Minimum | Required for | Install |
|---|---|---|---|
| bash | 4.0+ | Gate engine | brew install bash (macOS) / default on Linux |
| jq | 1.6+ | Policy evaluation | brew install jq / apt install jq |
| openssl | 3.x | Ed25519 signing | brew install openssl@3 / apt install openssl |
| Node.js | 18+ | MCP gate, receipt verification | Optional — bash gate works without it |
| Telegram | — | Human approval channel | Optional — without it, blocked actions are instant-denied |
CI-tested platforms: Ubuntu 22.04+ and macOS 14+ (matrix on every push). Debian 12+ is supported but not gated by CI — maintainers verify manually.
Run zlar doctor after installation to verify all dependencies.
bin/ Gate, receipt tools, witness, digest, registry, policy CLI
lib/ Shared libraries (crypto, session state, agent identity, receipt, human invariants)
adapters/ Framework hooks (claude-code, cursor, windsurf)
mcp-gate/ MCP TCP proxy gate (Node.js)
etc/ Policy, manifests, signing keys, standing approvals, receipt schema
tests/ Test suites (14 bash + 13 Node.js + 1 Python, 1000+ assertions)
Run all: bash tests/count-assertions.sh
docs/ Architecture decisions, manifest invariants, operations
docs/adr/ Architecture Decision Records
signal/ Agent-facing signal layer (thesis, origin, proof)
cedar-poc/ Cedar formal policy verification
Architectural choices are documented as ADRs:
| ADR | Decision |
|---|---|
| 001 | Deterministic enforcement, not AI |
| 002 | Bash as implementation language |
| 003 | Fail-closed as default |
| 004 | Ed25519 for signing |
| 005 | Manifest narrows policy, never widens |
| 006 | Structural independence from governed system |
- docs/troubleshooting.md — Common issues and fixes
- GOVERNANCE.md — How decisions are made, how invariants are amended
- SECURITY.md — Vulnerability disclosure, security principles
- CONTRIBUTING.md — How to contribute
- ADOPTERS.md — Who is using ZLAR
- LEGAL.md — Regulatory classification, liability, data processing
- signal/THESIS.md — Why intelligence in the monitor fails
- signal/ORIGIN.md — Why ZLAR exists
- signal/PROOF.md — No unauthorized action can execute on the governed path
Apache 2.0. See LICENSE.
Built by ZLAR Inc.