Tools
Clawthority
Clawthority Openclaw Plugin
Install
npm install &&
Configuration Example
{ "plugins": ["clawthority"] }
README
# Clawthority
**A semantic authorization runtime for AI agents. Define what your agent can do, enforce it at the boundary, and keep a human in the loop for what matters.**
Clawthority is a policy engine plugin for [OpenClaw](https://github.com/openclaw/openclaw) that sits between your AI agent and every tool it calls. It evaluates rules before execution happens โ not by asking the model to comply, but by intercepting the call at the code boundary. If policy says no, the call is never placed.
## What's new in v0.1
v0.1 is a ground-up restructure around a **two-stage enforcement pipeline** and a **canonical action registry**. It replaces the previous ABAC/JSON-rules engine and the UI/control-plane surface.
**Highlights**
- **Two-stage pipeline** โ Stage 1 capability gate (approval binding, TTL, one-time consumption, session scope) + Stage 2 CEE (protected paths, trusted domains, policy engine).
- **Action normalization** โ raw tool names are mapped to a canonical action registry (`filesystem.read`, `communication.external.send`, `payment.transfer`, โฆ) with risk + default HITL mode. Unknown tools fail closed as `unknown_sensitive_action`.
- **SHA-256 payload-bound approvals** โ an approval is cryptographically bound to `(action_class, target, payload_hash)`. Tampering with parameters after approval invalidates it.
- **IAuthorityAdapter** โ policy bundles and capability issuance sit behind a swappable adapter (`FileAuthorityAdapter` ships by default).
- **Versioned policy bundles** โ `data/bundles/active/bundle.json` with monotonic version + SHA-256 checksum, hot-reloaded within ~500ms.
- **Prompt-injection defense** โ `before_prompt_build` hook blocks common injection patterns in non-user content.
- **Source trust propagation** โ tool calls originating from `untrusted` content (web fetch, email, file read) are denied for high/critical-risk action classes, even with a valid approval.
- **HITL fully wired** โ Telegram and Slack approval adapters, approval messages include action / target / summary / expiry / token.
- **Fail closed** โ any error in the pipeline returns `deny`.
**Removed**
- Legacy ABAC/JSON rules engine (`src/engine.ts`, `src/rules.ts`, `data/rules.json`, `data/builtin-rules.json`)
- UI dashboard (`ui/`) and control-plane API (`control-plane-api/`)
- Raw tool-name matching in HITL (matching now happens on `action_class`)
## How it works
```
Agent picks a tool โ Clawthority intercepts
โ
โ normalize_action(toolName, params) โ { action_class, target, payload_hash }
โ buildEnvelope(...) โ ExecutionEnvelope
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโ Pipeline โโโโโโโโโโโโโโโโโโโโโโโโโ
โ Stage 1: Capability Gate โ
โ โข low-risk bypass โ
โ โข approval_required / TTL / payload binding โ
โ โข one-time consumption, session scope โ
โ โข untrusted source + high risk โ deny โ
โ โ
โ Stage 2: Constraint Enforcement Engine โ
โ โข protected path check (~/.ssh, /etc/, .env, โฆ) โ
โ โข trusted domain check (communication.external.send) โ
โ โข PolicyEngine.evaluateByActionClass(...) โ
โ โ
โ HITL: if required and no valid capability โ
โ โ issue approval via Telegram / Slack โ
โ โ deny 'pending_hitl_approval' โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโ allow โ tool executes
โโโ deny โ tool call never placed; ExecutionEvent logged
```
Every decision emits an `ExecutionEvent` to the append-only JSONL audit log with `action_class`, `target`, `decision`, `deny_reason`, `latency_ms`, and `context_hash`.
## Action registry
Tool calls are normalized to a canonical action class before policy evaluation. Examples:
| action_class | risk | default HITL | sample aliases |
|---|---|---|---|
| `filesystem.read` | low | none | `read_file`, `ls`, `glob`, `cat` |
| `filesystem.write` | medium | session | `write_file`, `edit_file`, `str_replace` |
| `filesystem.delete` | high | approve_once | `rm`, `delete_file`, `unlink` |
| `communication.external.send` | high | approve_once | `send_email`, `gmail`, `mail` |
| `payment.transfer` | critical | approve_once | `wire_transfer`, `transfer_funds` |
| `system.execute` | high | approve_once | `exec`, `bash`, `run_command` |
| `credential.write` | critical | approve_once | `set_secret`, `keychain_set` |
| `unknown_sensitive_action` | critical | approve_once | *(fallback for unknown tools)* |
**Parameter reclassification** โ a `filesystem.write` with a URL or email-shaped target is reclassified to `communication.external.send`; shell metacharacters in `system.execute` / `filesystem.write` params escalate risk to `critical`.
Full table in [docs/action-registry.md](docs/action-registry.md).
## Human-in-the-Loop
High-risk actions route to a human for approval via Telegram or Slack. Approvals are:
- **Payload-bound** โ SHA-256 of `(action_class | target | payload_hash)` is stored with the approval and re-verified at consumption. Any parameter change invalidates the token.
- **One-time** (`approve_once`) or **session-scoped** (`session`) โ session approvals are keyed on `${session_id}:${action_class}`.
- **TTL-limited** โ default 120 seconds, configurable.
- **UUID v7** โ time-sortable approval IDs.
Example approval message:
```
Action: communication.external.send
Target: [email protected]
Summary: communication.external.send โ [email protected]
Expires: 2026-04-14T12:34:56Z
Token: 01f2e4b8-...
```
Details: [docs/human-in-the-loop.md](docs/human-in-the-loop.md).
## The Skill vs The Plugin
| | **The Skill** | **The Plugin** |
|---|---|---|
| **Lives in** | Context window (model sees it) | Execution path (between agent + tools) |
| **Enforces via** | Model reasoning โ asks it to comply | Code boundary โ before call is placed |
| **Can be bypassed?** | Yes โ prompt injection, loop misfire | No โ operates outside the model's loop |
| **Gives you** | Observability + soft stop | Hard enforcement + immutable audit log |
> *A skill asks the model to enforce. A plugin enforces regardless of what the model decides.*
## Quick start
### Install
```bash
git clone https://github.com/Clawthority/clawthority ~/.openclaw/plugins/clawthority
cd ~/.openclaw/plugins/clawthority
npm install && npm run build
```
Register in `~/.openclaw/config.json`:
```json
{ "plugins": ["clawthority"] }
```
### Configure
`openclaw.plugin.json` fields (all optional):
```json
{
"bundlePath": "data/bundles/active",
"proposalPath": "data/bundles/proposals",
"auditLogFile": "data/audit.jsonl",
"cee": {
"trustedDomains": ["company.com"],
"protectedPaths": ["~/.ssh/", "~/.gnupg/", "/etc/", "~/.env", ".env", "~/.aws/"]
},
"hitl": {
"telegram": { "botToken": "...", "chatId": "..." },
"slack": { "botToken": "xoxb-...", "channelId": "C0...", "signingSecret": "...", "interactionPort": 3201 }
}
}
```
### Policy bundles
Rules live in `data/bundles/active/bundle.json`:
```json
{
"version": 1,
"rules": [
{ "effect": "permit", "action_class": "filesystem.read", "priority": 10 },
{ "effect": "forbid", "action_class": "system.execute", "priority": 100 },
{ "effect": "forbid", "action_class": "payment.transfer", "priority": 90 }
],
"checksum": "<SHA-256 of JSON.stringify(rules)>"
}
```
The adapter watches the bundle directory, validates version monotonicity and checksum, and hot-reloads on change. In production, set the `active/` directory read-only for the Clawthority process user; only your deployment pipeline should have write access.
## Hooks
| Hook | Purpose |
|---|---|
| `before_tool_call` | Primary enforcement โ normalize, run two-stage pipeline, emit audit event |
| `before_prompt_build` | Prompt-injection defense โ blocks known injection patterns in non-user content |
## Project structure
```
src/
index.ts โ plugin entry, hook registration, wiring
types.ts โ ExecutionEnvelope, Intent, Capability, CeeDecision, โฆ
envelope.ts โ buildEnvelope, uuidv7, computePayloadHash, computeContextHash
audit.ts โ JsonlAuditLogger
enforcement/
pipeline.ts โ executePipeline orchestrator
normalize.ts โ canonical action registry + normalizer
stage1-capability.ts โ Stage 1 capability gate
stage2-policy.ts โ Stage 2 CEE factory
policy/
engine.ts โ PolicyEngine + evaluateByActionClass
bundle.ts โ validateBundle (schema, monotonicity, checksum)
types.ts โ Rule, Effect, RateLimit
rules/default.ts โ default action-class rules
adapter/
types.ts โ IAuthorityAdapter, ApprovalRequest, PolicyBundle
file-adapter.ts โ FileAuthorityAdapter (watches bundles/active)
hitl/
approval-manager.ts โ payload-bound approvals, session + approve_once
matcher.ts โ action_class dot-notation matching
telegram.ts, slack.ts โ approval channel adapters
data/
bundles/
active/bundle.json โ active policy bundle
proposals/ โ staged bundle proposals
audit.jsonl โ append-only execution-event log
docs/ โ architecture, action registry, HITL, configuration
```
## Development
```bash
npm install
npm run dev # watch mode
npm run build # production build
npm test # vitest
```
## Documentation
| Guide | Description |
|---|---|
| [Architecture](docs/architecture.md) | ExecutionEnvelope, two-stage pipeline, adapter swap path |
| [Configuration](docs/configuration.md) | Full config schema with examples |
| [Action Registry](docs/action-registry.md) | All canonical
... (truncated)
tools
Comments
Sign in to leave a comment