Guardrail Quickstart

Policy enforcement for programmatic tool execution. 15µs p50 latency. Zero hallucinations. Ungameable. Works with AI agents, CI/CD, automation, and shells.

Try it without installing

The quickest way to see it work is the demo walkthrough — ten real commands with the verdicts the engine actually returned, plus a copy-pasteable curl you can point at your own commands. No signup.

Install the CLI (free tier, no source needed)

The CLI installs with one command on macOS and Linux (x86_64 and arm64) and runs checks locally — no sudo, no source license. macOS support is new and in active testing — if you hit a rough edge, tell us and we’ll fix it fast:

curl -fsSL https://downloads.ellmstack.dev/install.sh | bash
guardrail link                                         # pair this machine with your console account
guardrail check --tool Bash --target "rm -rf /"
# → verdict: deny — rm with destructive flags

The installer verifies the download’s SHA-256, installs to ~/.local/bin, and guardrail link delivers your API key encrypted — it is never printed and never appears in a URL. Overrides: GUARDRAIL_RELEASE_BASE, INSTALL_DIR, GUARDRAIL_FORCE_PLATFORM. Sign up in the console when link asks you to confirm; the free tier covers 8,000 checks/month.

Self-hosted (Docker)

The source ships to licensees under a commercial license agreement — request access and we’ll get you set up. Once you have it:

# Start the stack (engine + console) — builds locally from the shipped source
docker compose up -d

# Check a safe action
curl -s -X POST http://localhost:9090/check \
  -H "Authorization: Bearer <your-key>" \
  -H "Content-Type: application/json" \
  -d '{"tool_name":"Bash","target":"cargo test","params":{}}' | jq .verdict
# → "allow"

# Check a dangerous action
curl -s -X POST http://localhost:9090/check \
  -H "Authorization: Bearer <your-key>" \
  -H "Content-Type: application/json" \
  -d '{"tool_name":"Bash","target":"rm -rf /","params":{}}' | jq .verdict
# → "deny"

# Check an unknown action (fails safe → escalate)
curl -s -X POST http://localhost:9090/check \
  -H "Authorization: Bearer <your-key>" \
  -H "Content-Type: application/json" \
  -d '{"tool_name":"Bash","target":"frobnicate_widget","params":{}}' | jq .verdict
# → "escalate"

Checks are authenticated with Authorization: Bearer <key> by default (keys are issued by the console). On a loopback-only install with no keys configured, you can set GUARDRAIL_NO_AUTH=1 instead.

Protecting a Claude Code Agent (5 Minutes)

Claude Code calls tools like Bash, Read, Write, Edit, WebFetch, WebSearch. Each tool call goes through the guardrail before execution.

Step 1: Start the guardrail

docker compose up -d

Step 2: Create your policy

The bundled policy template already covers Claude Code tools (file_read, shell_exec, run_command, etc.). Add your own:

# Deny: never allow deleting production data
[[category]]
name = "prod_destructive"
verdict = "deny"

[[action]]
name = "delete_prod_db"
category = "prod_destructive"

Restart the server to pick up policy changes — there is no hot reload.

Step 3: Intercept tool calls

The guardrail exposes POST /check. Your agent framework (or a thin middleware) sends each tool call before execution:

import requests

def check_tool(tool_name, target, params=None):
    """Returns 'allow', 'deny', or 'escalate'."""
    r = requests.post("http://localhost:9090/check", json={
        "tool_name": tool_name,
        "target": target,
        "params": params or {}
    }, headers={"Authorization": "Bearer <your-key>"}, timeout=1)
    return r.json()

# In your agent loop:
verdict = check_tool("Bash", "rm -rf /")
if verdict["verdict"] == "deny":
    print(f"BLOCKED: {verdict['reason']}")
    return  # Don't execute

For Claude Code specifically, you can wrap claude with a pre-execution hook that queries the guardrail, or deploy it as a transparent proxy in front of any agent API.

How It Works

Agent Tool Call → Guardrail → Is this in my policy?
                                ├─ Yes, deny category  → BLOCK (15µs)
                                ├─ Yes, allow category → ALLOW (15µs)
                                └─ Unknown            → ESCALATE (fails safe)

The guardrail’s classification path doesn’t use regex, prompts, or an LLM. (Regexes appear only in the optional PII/sensitive-content redaction layers — never in the verdict path.)

It compiles your policy (TOML) into a Rete forward-chaining network. Every check is a deterministic inference: insert facts → run rules to fixpoint → read verdict. The same input always produces the same output — bit-for-bit, across restarts, across machines.

Why this matters: a prompt-based guardrail can be socially engineered. A regex filter can be bypassed with encoding tricks. A Rete network with content-addressed hashing and obfuscation-resistant normalization cannot.

Policy: What You Define

ConceptTOMLWhat it does
Category[[category]] name, verdict = “deny” or “allow”A bucket (destructive_op, exfiltration, auth_disable) with a verdict
Action[[action]] name, categoryMaps a tool name to a category
Flag rule[[flag_rule]] action, flags, categoryrm with -rf flags → destructive; rm alone → escalate
Param key[[param_key]] name, categoryFlags capability-granting parameters (e.g. a --token key on a read-only tool)
Bridge[[bridge]] sub, supergit_destructive IS_A destructive_op — transitive inheritance

Adding a new dangerous action is one line of TOML. No recompile. Restart the server to pick up policy changes (there is no hot reload yet).

Verdicts

VerdictMeaning
AllowSafe — proceed
DenyDangerous — block
EscalateUnknown — ask a human (or your optional LLM judge)

Deny beats Allow. Escalate beats nothing — if an action isn’t classified, it escalates (fail-safe).

Performance

Measured on ordinary x86 hardware. No GPU. No cloud dependency. Full benchmark →

MetricValue
Per-check latency (p50, pipeline)15µs
Per-check latency (p50, 1M realistic commands)19µs
Throughput (single core, sequential)37,745 checks/sec
Throughput (14 threads, parallel)22,096 checks/sec — parallel is slower (see benchmark)
Memory per check~65 KB
Cross-ecosystem accuracy115/115 dangerous calls denied, 0 false-ALLOW

Custom Policies: Real Examples

“Never allow shell commands with pipes to interpreters”

[[action]]
name = "curl_pipe_to_interpreter"
category = "destructive_op"

“My CI agent can write files but not delete them”

[[action]]
name = "file_write"
category = "read_only_op"

[[action]]
name = "delete_file"
category = "destructive_op"

“SOC2: prevent exfiltration of customer data”

[[category]]
name = "customer_data_exfil"
verdict = "deny"

[[action]]
name = "read_customer_db"
category = "customer_data_exfil"

[[action]]
name = "export_customer_csv"
category = "customer_data_exfil"

API Reference

The full API surface (18+ endpoints including approvals, events, audit export, and sessions) is covered in the integration guide. The core three:

POST /check

{
  "tool_name": "Bash",
  "target": "rm -rf /",
  "params": {"cwd": "/home/user"}
}

Response:

{
  "verdict": "deny",
  "tier": "deterministic",
  "action": "rm_rf",
  "confidence": "high",
  "strategy": "exact_command",
  "reason": "rm with destructive flags",
  "ellm_trace": ["rm_rf --rel1--> destructive_op", "destructive_op --rel225--> rm_rf"],
  "latencies": {
    "mapper_us": 2,
    "ellm_us": 13,
    "llm_us": 0,
    "total_us": 15
  }
}

GET /health

{"status": "ok"}

GET /metrics

{
  "total_checks": 15432,
  "allow_count": 12100,
  "deny_count": 3100,
  "escalate_count": 232,
  "avg_latency_us": 19,
  "uptime_secs": 86400
}

Deployment Options

OptionWhen to use
docker compose upSingle machine, quick start
KubernetesProduction, multi-replica (manifests ship with the source)
Systemd serviceBare metal, no containers
Embedded (Rust library)In-process, zero network latency
Python SDK / MCP serverAgent integrations — python-sdk
C FFINot yet available

Next Steps

  1. See it decide: read the demo walkthrough, or self-host with docker compose up
  2. Write your policy: copy the bundled template, add your actions and categories — see policy tuning
  3. Understand the boundary: threat model — what we protect against and the known gaps
  4. Integrate: wire POST /check into your agent’s tool execution loop — integration guide
  5. Go to production: deployment guide — TLS, monitoring, SLI/SLO targets