clawpatrol gates agent traffic against HCL rules at the wire
Security firewall for agents
At a glance
- What is it?
- clawpatrol is a Go proxy that sits between AI agents and production systems, parses their traffic per protocol and evaluates CEL conditions over HCL rules before a request is forwarded. It suits teams letting agents run against real infrastructure, and it is a network control rather than a sandbox.
- Who is it for?
- Adopt clawpatrol if you let an agent reach a real database, cluster or API and you need a policy point that can deny a request or hold it for human approval before it lands. Do not adopt it as a substitute for sandboxing the agent itself, since it only sees what the agent sends.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 36 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.
Star history
- denoland/clawpatrol1,093 ★ · +6
| Repository | 2026-10-19 | 2026-11-07 |
|---|---|---|
| denoland/clawpatrol | 1.1k | 1.1k |
6 Stars in the last 19 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
It sits on the wire and decides before the request arrives
clawpatrol is described in one line as the security firewall for agents. The mechanism is a proxy: clawpatrol sits between your agents and prod, parses their traffic at the wire, and gates each action against rules you write in HCL.
The example the documentation leads with is the reason the project exists. You can block destructive SQL, or pause kubectl delete pod until a human approves it, before the request reaches Kubernetes.
That ordering is the point. A guard inside the agent, a prompt telling the model not to delete the pod, is advisory and can be argued with or ignored. A guard on the wire is not part of the agent's context, the agent does not know it is there, and the request is simply not forwarded until the policy says it may be. The trust boundary is the network path rather than the instruction.
The practical consequence is that clawpatrol is a separate binary and a separate operator. You write HCL, you run a gateway, and the agent connects through a tunnel rather than reaching the cluster directly. The rules are reviewed like firewall rules, in a text file, with a diff.
The project lives under the denoland organisation and is written in Go, with a MIT licence, and the site is clawpatrol.dev.
Conditions are CEL expressions over protocol-specific facts
The rule language is HCL, the same configuration format Terraform uses, and the conditions inside a rule are CEL expressions. The rule given as a real example from the project's own production config is short:
rule "k8s-no-secrets" {
endpoint = k8s-prod
condition = "k8s.resource == 'secrets'"
verdict = "deny"
reason = "Secret values must not leave the cluster via the agent"
}The shape is worth noting. A rule binds to an endpoint, carries a condition, a verdict and a reason. The reason field is not decoration, it is what an approval UI shows the human who has to decide, and it is what gets logged when a request is blocked.
The condition language is where the protocol knowledge lives. Conditions are CEL expressions over wire-level facts the gateway extracts per protocol: SQL verbs and table names for Postgres and ClickHouse, resource, verb and namespace for Kubernetes, and method, path, headers and body for HTTP. The full set of facts lives in the config reference.
This is a design decision with a tradeoff attached. Extracting facts means the gateway parses the protocol rather than just relaying bytes, which is what makes a rule like k8s.resource == 'secrets' possible. It also means the facts available to a condition depend entirely on the protocol: an HTTP rule cannot ask about a table name, and a SQL rule cannot ask about a namespace. A policy you cannot express in the available facts is a policy the gateway cannot enforce, no matter what the rule file says.
Three deployment shapes: gateway, join, and run
The tool has three commands, and they correspond to three different ways of routing agent traffic through the gateway.
clawpatrol gateway config.hcl # run the proxy itself
clawpatrol join <gateway-url> # join a gateway
clawpatrol run claude # wrap one agent's process treeThe gateway is the proxy itself, a single binary that loads your HCL config and accepts clients tunnelling in via WireGuard or Tailscale. Everything else connects to it.
The join command brings up a WireGuard tunnel that routes the whole host. That is the blunt instrument: every request the host makes toward your infrastructure goes through the policy point, including the ones you did not mean to intercept.
The run command is the precise one. It wraps one agent's process tree and opens a per-process tunnel, on Linux via netns and on macOS via NetworkExtension, and only the wrapped command's traffic goes through the gateway. The example names claude, so the intended use is wrapping a specific agent binary rather than intercepting a machine.
The difference between join and run is the difference between a network perimeter and a per-application control. A per-process network namespace is a stronger isolation story than a host-wide tunnel, because the agent's traffic is distinguishable from everything else on the box, which means you can also attribute traffic to a process when you are reviewing a decision log.
The macOS path deserves a note because it is not a sandbox. NetworkExtension on macOS is a system extension mechanism, and running it on a developer machine means installing system-level components for a tool that is meant to be your policy layer.
Protocol examples and approvers are the template library
The examples/ directory in the repository is the practical entry point, and the file names describe the coverage: gateway.example.hcl for an annotated starting template, protocol-sql.hcl, protocol-k8s.hcl and protocol-https.hcl for the three protocol families, rules-block.hcl for blocking rules, and approver-human.hcl and approver-llm.hcl for the two approval paths.
The distinction between a human approver and an LLM approver is the interesting one. The README's own example describes pausing kubectl delete pod until a human approves it, and the presence of a separate LLM approver file means clawpatrol can also delegate the decision to a model. That is a meaningful difference in trust, and the example files exist so you can see the two configurations side by side rather than infer the difference from documentation.
A human approver in the loop means a latency and an attention cost. An LLM approver means the approval step inherits the same class of failure you are trying to contain, since a model asked to judge whether a request is dangerous is itself promptable. The documentation does not say which is safer, so this is a decision to make rather than a setting to default.
The configuration documentation is split in two: a getting started page that walks through a first config end to end, and a config reference described as the auto-generated field reference. Auto-generated matters here, because the field reference will stay in step with the binary, while the example files are maintained by hand and can drift.
The dependency list shows a real proxy with a real protocol stack
The go.mod is unusually informative for a small tool, and it is worth reading to understand what the gateway actually does.
The parsing layer is what you would expect. There are two SQL parsers, github.com/AfterShip/clickhouse-sql-parser and github.com/pgplex/pgparser, and a ClickHouse client, github.com/ClickHouse/clickhouse-go/v2, plus ch-go. The condition engine is google/cel-go at 0.30.0, and the configuration parser is hashicorp/hcl/v2 at 2.24.0 with zclconf/go-cty for the values. The rule language is therefore built from the same primitives as Kubernetes admission control, which is a fair description of what it is emulating.
The transport layer is where the weight is. golang.zx2c4.com/wireguard provides the tunnel, and tailscale.com at 1.96.5 is a full dependency for the alternative transport. gvisor.dev/gvisor is a userspace network stack, which is what makes per-process network namespace interception possible without privileged kernel modules. miekg/dns handles DNS. github.com/refraction-networking/utls is there for TLS fingerprinting behaviour, and andybalholm/brotli plus klauspost/compress handle compression on the wire.
There is also a security supply chain component, with sigstore/sigstore-go and the protobuf specs, and hashicorp/go-plugin, which is the plugin mechanism. hashicorp/go-hclog provides structured logging, and the OpenTelemetry packages cover traces and metrics with an OTLP exporter, so the gateway is instrumented for a standard observability backend.
The module targets Go 1.26.6. The presence of gvisor, tailscale.com and the plugin system explains the binary size, and the Makefile documents it: a release build with -s -w and -trimpath drops the binary from about 88 MB to about 62 MB without changing runtime behaviour.
Install is a curl pipe, and the dashboard is a Deno bundle
Installation is one line:
curl -fsSL https://clawpatrol.dev/install.sh | shBuilding from source needs Go and Node.js, via make. The README does not mention Deno, but the Makefile does: the build target depends on a dashboard target that runs deno install and deno task build inside the dashboard directory, and the go-lint target depends on the same dashboard target because the //go:embed in dashboard/embed.go has to resolve at compile time.
So the source build needs Go, Node.js and Deno, and it produces a Go binary with an embedded web dashboard. The Makefile comment explains that depending on dashboard inside go-lint is what makes a clean checkout work without manual ordering, which is a small sign of how many people hit that problem.
The other targets are ordinary. The release target strips the symbol table and DWARF and rewrites source paths, matching what the GitHub release workflow does. The fmt and fmt-check targets run gofmt on the tracked Go sources and the Deno formatter on the dashboard, and lint runs golangci-lint with a five minute timeout alongside the dashboard lint. The install target copies the built binary to ${PREFIX:-$HOME/.local/bin}/clawpatrol.
One detail in the Makefile deserves a note, because it is the kind of thing that bites. The gofmt target deliberately excludes third_party/, and the comment says that directory holds a verbatim tailscale.com tree that must not be reformatted, with a pointer to third_party/tailscale/PATCH.md. Vendoring a full upstream tree and patching it is a strategy with real maintenance cost, and at least here it is documented rather than surprising.
MIT licensed, at v0.5.14, with three releases in a single day
The licence is MIT, with LICENSE.md in the repository as the authoritative text, and this is a licensing statement rather than legal advice.
The version record shows how fast this is moving. v0.5.14, v0.5.13 and v0.5.12 were all released on 2026-10-03, at 06:58, 04:32 and 02:12 respectively, and the last push to the repository was on 2026-10-03 as well. The repository is not archived.
Three releases in one day in a 0.5 line is a signal about the maturity of the project rather than about its quality. It means the tool is being used and changed at a rate where a patch release may carry a behavioural change you did not ask for, so pinning a version and reading the release notes before each upgrade is the sensible routine. The 0.x version number also means the author is not claiming a stable interface yet, which is fair for a project whose configuration reference is auto-generated from the binary.
The repository layout supports the impression of an active project with a real surface area. There is a cmd/ directory, internal/ for the implementation, shared/, a pluginsdk/, a site/ for the documentation, doc/, a dashboard/, macos/ for the NetworkExtension component, third_party/, examples/, plus SECURITY.md, CONTRIBUTING.md, AGENTS.md, a .golangci.yml and install.sh.
The pluginsdk/ directory alongside hashicorp/go-plugin in the dependencies suggests the protocol parsers are meant to be extendable, which is the right shape for a tool whose value is entirely in how well it understands the protocols you use.
Editorial conclusion
Adopt clawpatrol if you let an agent reach a real database, cluster or API and you need a policy point that can deny a request or hold it for human approval before it lands. Do not adopt it as a substitute for sandboxing the agent itself, since it only sees what the agent sends. Before you deploy, read the protocol examples in the repository, since the facts available to a condition depend on the protocol, and check whether the approver you need exists, because the example files distinguish a human approver from an LLM approver.
Frequently asked questions
What does clawpatrol do and where does it sit?
It is a proxy that sits between your agents and prod, parses their traffic at the wire and gates each action against rules you write in HCL. You can block destructive SQL or pause kubectl delete pod until a human approves it before the request reaches Kubernetes.
How do I install clawpatrol?
The documented install is curl -fsSL https://clawpatrol.dev/install.sh | sh. From source, run make, which requires Go and Node.js, and the Makefile also builds a dashboard bundle with Deno as part of that target.
What language are clawpatrol rules written in?
Rules are HCL blocks with a condition that is a CEL expression over facts the gateway extracts per protocol, such as SQL verbs and table names, Kubernetes resource, verb and namespace, or HTTP method, path, headers and body.
What is the difference between clawpatrol run and clawpatrol join?
The run command wraps one agent's process tree and opens a per-process tunnel, via netns on Linux or NetworkExtension on macOS, so only that command's traffic goes through the gateway. The join command brings up a WireGuard tunnel that routes the whole host.
Does clawpatrol support human approval for risky actions?
Yes. The README's example describes pausing kubectl delete pod until a human approves it, and the repository's examples directory contains both approver-human.hcl and approver-llm.hcl for the human and model approval paths.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/denoland-clawpatrol)Star history chart for your README
[](https://hysenlabs.com/projects/denoland-clawpatrol)Was this useful?