ClawKeeper: Safety Middleware for Tool-Using Agents
ClawKeeper: Comprehensive Safety Protection for OpenClaw Agents Through Skills, Plugins, and Watchers (aka The Norton for OpenClaw)
At a glance
- What is it?
- ClawKeeper is a Python guard layer that sits between an agent and its tools, blocking risky calls and redacting sensitive results. It is at version 0.2.0.dev0 and classified as Alpha, so adoption means reading the guard source.
- Who is it for?
- Adopt ClawKeeper if you run a tool-using agent and want a small, inspectable Python guard layer you can read in an afternoon. Do not adopt it if you need a stable, versioned security product: the package is 0.2.0.dev0, classified Alpha, and has no releases.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 30 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap ClawKeeper fills between an agent and its tools
An agent that can run shell commands, read files and call HTTP endpoints has no inherent sense of what it should not do. The model decides, the tool executes, and nothing in between checks the decision. ClawKeeper inserts that check. The README describes it as "host-agnostic safety middleware for tool-using agentic systems" that can be wired into Hermes Agent, MCP tools, HTTP bridges, OpenClaw-style runtimes, or a custom host.
The intended user is a developer already running an agent loop who wants a guard layer without patching the host. The README states that installing the Hermes adapter requires "No Hermes patching". That constraint shapes the whole design: guards hook into the pre-tool and post-tool-result path, so the host keeps its own execution model.
The threats named in the README are concrete: prompt injection, credential reads, credential exfiltration chains, unsafe shell execution, protected-path access, SSRF-like URLs, encoded second-stage payloads, and poisoned tool output. That list is a useful scope statement. It is about what a single tool call or its result looks like, not about the agent's long-term behaviour.
How the Judge, guards and Watcher divide the work
The mechanism has three layers. The first is the guard chain. The README says the default set covers dangerous shell execution, protected path access, unsafe URL and SSRF patterns, script-body and dynamic-path inspection, base64 or hex encoded payloads, credential discovery plus network exfiltration chains, poisoned return content, and credential redaction. These are pattern-level checks on a proposed call or a returned result.
The second layer is the Judge, exposed both as a Python class and as an HTTP service. Hosts that cannot import the Python package call the server instead. The README lists the endpoints: /v1/judge, /v1/event, /v1/audit, /v1/scan/logs, /v1/scan/skill, plus maintenance harden and rollback routes. That split matters because it decouples the safety decision from the language the agent is written in.
The third layer is the Watcher, an optional daemon. The README describes it as reasoning over intent, recent tool history, deterministic findings, and proposed tool calls, and says it is useful "when single-command rules are not enough and the decision depends on intent, recent tool history, or multi-step drift". It also feeds back: Watcher catches can synthesize learned patterns, persist them under ~/.clawkeeper/, and hot-reload them into the live guard layer. That is the self-improving part, and it is also the part with the most moving pieces.
Installing ClawKeeper and running the HTTP core
The README gives a clone, virtual environment and editable install. Note that the install target is the Python package clawkeeper-core, version 0.2.0.dev0, and the project requires Python 3.11 or newer.
git clone git@github.com:SafeAI-Lab-X/ClawKeeper.git
cd ClawKeeper
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"The README then suggests a sanity check with the test suite. If your environment is set up correctly, pytest collects the tests under tests/ and reports the results.
pytest -qFor hosts that cannot import the package, the console script starts the HTTP core. The README shows the health check on port 7474.
clawkeeper-server
curl http://127.0.0.1:7474/v1/healthIf you use Hermes, the adapter is a single install call. The snippet below is the README's example, including the placeholder arguments you would replace with your own agent.
from run_agent import AIAgent
from clawkeeper_core import Judge
from clawkeeper_core.adapters.hermes import install as install_clawkeeper
agent = AIAgent(...)
install_clawkeeper(Judge(), agent)
agent.run("your task")The README states that this installs the default pre-tool guard chain and post-tool-result scanners.
Running the Watcher daemon and what it costs you
The Watcher is not part of the default path. It needs an OpenAI-compatible endpoint, configured through three environment variables, and it listens on its own port. The README uses an OpenAI model name as the example value.
export CK_WATCHER_API_KEY="$OPENAI_API_KEY"
export CK_WATCHER_BASE_URL="$OPENAI_BASE_URL" # optional, OpenAI-compatible
export CK_WATCHER_MODEL="gpt-5.5" # or your configured model
python -m clawkeeper_core.watcher.daemon
curl http://127.0.0.1:9099/watcher/healthWiring it into Hermes is an extra argument to the same install call.
install_clawkeeper(
Judge(),
agent,
watcher_url="http://127.0.0.1:9099",
)The trade-off is visible in the configuration. The Watcher reasons over intent and recent tool history, which means that history leaves your process and goes to whichever endpoint CK_WATCHER_BASE_URL points at. The README does not describe a local-model-only mode or a redaction step before the Watcher call. If your tool history can contain credentials or customer data, that is the first thing to verify before enabling the daemon. The deterministic guard chain does not have this property; it runs in-process.
Where the guard layer stops being enough
The README is explicit that the policies are "intentionally small and inspectable". That is an honest description of a real limitation. A small pattern set covers known shapes: a shell command that matches a dangerous form, a URL that looks like SSRF, a base64 blob in a script body. It does not cover a sequence of individually benign calls that adds up to something harmful. That gap is exactly what the Watcher exists for, and the Watcher is optional, so a default install has it.
There is a second boundary. The self-improving loop persists learned patterns under ~/.clawkeeper/ and hot-reloads them. The README does not document what happens when a learned pattern is wrong, how patterns are reviewed before they go live, or how you remove one. The HTTP surface includes maintenance harden and rollback routes, so a rollback path exists, but the README does not describe its semantics. Treat the learned-pattern store as state you own and need to inspect.
Finally, this is not a sandbox. ClawKeeper decides whether a tool call proceeds; it does not contain the process if a call it allowed turns out to be harmful. If your requirement is isolation rather than policy, a container or VM boundary is the right tool and ClawKeeper is not a substitute for it.
ClawKeeper against a general agent framework's built-in hooks
The obvious alternative is to use the guard hooks your agent framework already ships, or to write the checks yourself where the tool call is dispatched. A framework hook is co-located with the loop, has no extra process to run, and shares the framework's release cadence.
The difference in approach is the HTTP core. ClawKeeper exposes the Judge over HTTP on port 7474, with endpoints for judging, events, audit, log scanning and skill scanning. That means a TypeScript or Go host can get the same decisions without reimplementing them, and the safety logic lives in one place across several agents. The repository reflects this: the top level contains adapters_js/ alongside clawkeeper_core/, and the primary language listed for the repository is TypeScript even though the installable package is Python.
The cost of that choice is a second service to operate and a network hop in the decision path. If you run exactly one agent in one language and you are happy maintaining its hooks, the HTTP core buys you little. If you run several hosts, or you want one audit trail across them, the split is the reason to pick this over per-framework guards.
Maintenance, licence and what to verify before adopting
The last push to the repository was on 2026-08-17, and the repository is not archived. There are no retrieved releases, so the install path is the editable install from the default branch rather than a pinned artifact. The package version in pyproject.toml is 0.2.0.dev0 and the classifier is "Development Status :: 3 - Alpha". Both facts point the same way: expect the API and the guard set to move, and pin a commit if you depend on either.
The declared licence is Apache-2.0, stated in both the README and the pyproject.toml license field. The repository metadata supplied here lists the licence as unknown, which is a discrepancy worth resolving with the maintainers before you rely on the Apache-2.0 terms. That is a factual gap, not a legal opinion; if the licence matters to your distribution, get it confirmed.
On upgrade cost, the README does not document a migration path between versions, and the presence of README_v02.md and a legacy/ directory at the top level suggests the project has already reorganized once. The practical step is to read clawkeeper_core/guards/ before upgrading and diff it against what you reviewed, because the guard set is the thing your security posture actually rests on. The development section points to tests/redteam/ and experiments/ for red-team fixtures and benchmark scripts, which is where you would look to see what the guards are expected to catch.
Editorial conclusion
Adopt ClawKeeper if you run a tool-using agent and want a small, inspectable Python guard layer you can read in an afternoon. Do not adopt it if you need a stable, versioned security product: the package is 0.2.0.dev0, classified Alpha, and has no releases. Before wiring it in, read clawkeeper_core/guards/ to confirm the shipped policies match your threat model, and decide whether you need the optional Watcher at all, because it sends tool history to an external model endpoint.
Frequently asked questions
What does ClawKeeper actually do to an agent's tool calls?
It sits between the agent and its tools, running a pre-tool guard chain and post-tool-result scanners. The README says it can block risky tool calls and redact sensitive tool results, covering things like unsafe shell execution, credential reads and SSRF-like URLs.
Do I need the Watcher to use ClawKeeper?
No. The README states the Watcher is optional and is useful when single-command rules are not enough, for example when the decision depends on intent or recent tool history. The deterministic guard chain runs without it.
Can I use ClawKeeper from a non-Python agent?
Yes, through the HTTP core. The README gives clawkeeper-server and a health check on http://127.0.0.1:7474/v1/health, with endpoints including /v1/judge, /v1/event and /v1/audit for hosts that cannot import the Python package directly.
Community notes