npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ai-permissions-layer

v0.1.3

Published

Offline-first middleware for AI agent tool call permissions. Intercepts tool calls, applies rules, returns ALLOW | BLOCK | REQUIRES_APPROVAL.

Readme

AI Permissions Layer

Middleware that intercepts AI agent tool calls, applies your rules, and returns allow, block, or require approval. Use it to control what your agent can do—block dangerous actions, require approval for sensitive ones, and allow safe operations by default.


Table of Contents


Quick Start (OpenClaw)

openclaw plugins install ai-permissions-openclaw
openclaw gateway restart
openclaw ai-permissions compile

The first compile creates ~/.openclaw/rules.yaml with starter rules if none exist. Edit rules.yaml, run compile again when you change rules, and you're done. No extra API keys needed if you've run openclaw onboard.


Writing Rules

Rules define what the agent can do. Each rule has an action and applies to one or more tools.

Actions

| Action | Behavior | |--------|----------| | block | Tool is never allowed. The agent sees an error and cannot proceed. | | require_approval | Tool is blocked until you reply APPROVE <uuid> in chat. One-time approval per request. | | allow | Tool runs without asking. |

Plain-Text Format (YAML)

Write rules in plain English, one per line, each starting with -:

# Block dangerous actions
- block gmail.delete and gmail.batchDelete - never auto-delete emails
- block payments and money transfers - no financial actions

# Require approval before risky operations
- require approval before exec, bash, or process - ask before running commands
- require approval before write, edit, apply_patch - ask before file changes

# Allow safe read-only operations
- allow read, search, list - safe read-only operations
- allow gmail.list and gmail.get - reading emails is fine

Compile these into JSON with openclaw ai-permissions compile or npx ai-permissions-compile --openclaw. The compiler uses an LLM to infer tool names from your wording.

Compiler Language Hints

The compiler maps natural language to actions:

| You write | Action | |-----------|--------| | "block", "don't allow", "never" | block | | "ask me", "prompt me", "require approval", "before X" | require_approval | | "allow", "ok", "permit" | allow |

Include tool names when you know them (e.g. gmail.delete, write, exec). The compiler will infer others (e.g. "payments" → payments, "money transfers" → money_transfers).

Compiled JSON Format

After compiling, rules become JSON:

{
  "rules": [
    { "action": "block", "tool": "gmail.delete", "reason": "never auto-delete emails" },
    { "action": "require_approval", "tool": "write", "reason": "ask before file changes" },
    { "action": "allow", "tool": "read", "reason": "safe read-only operations" }
  ]
}

Each rule: action, tool, reason. The plugin loads this file; you typically edit the YAML and recompile.

OpenClaw Tool Names

Common OpenClaw tools to reference in rules:

| Category | Tools | |----------|-------| | Files | read, write, edit, apply_patch | | Runtime | exec, bash, process | | Gmail | gmail.list, gmail.get, gmail.send, gmail.delete, gmail.batchDelete | | Browser | browser_*, web_* | | Internal | pairing, device-pair, openclaw.* (these bypass rules) |

Internal tools (pairing, device-pair, openclaw.*) are never intercepted.

Rule Precedence

  • block wins over require_approval when both match the same tool.
  • First matching rule applies. Order matters when you have overlapping rules.
  • When no rule matches, behavior is set by defaultWhenNoMatch (default: require_approval).

OpenClaw Setup & Usage

Installation

openclaw plugins install ai-permissions-openclaw
openclaw gateway restart

Compile Rules

# Default: ~/.openclaw/rules.yaml → ~/.openclaw/ai-permissions-rules.json
openclaw ai-permissions compile

# Custom input
openclaw ai-permissions compile my-rules.yaml

# Custom input and output
openclaw ai-permissions compile my-rules.yaml ~/.openclaw/ai-permissions-rules.json

First run: If ~/.openclaw/rules.yaml doesn't exist, it is created with starter rules and compiled.

Credentials: Uses OpenClaw's primary model from ~/.openclaw/openclaw.json and credentials from ~/.openclaw/.env. Run openclaw onboard first if you haven't.

Workflow

  1. Edit ~/.openclaw/rules.yaml
  2. Run openclaw ai-permissions compile
  3. Rules take effect immediately (plugin reloads on each tool call)
  4. Restart the gateway only when changing plugin config

Rule Reference

Exact Tool Match

Rules match by exact tool name:

- block gmail.delete - no auto delete
- allow read - read-only ok

Multiple Tools per Rule

List tools in one rule (compiler creates one JSON rule per tool):

- block gmail.delete and gmail.batchDelete - never auto-delete emails
- require approval before write, edit, apply_patch - ask before file changes

Advanced: toolPattern and intentPattern (JSON only)

For programmatic use, compiled rules can include:

  • toolPattern — regex to match tool names (e.g. gmail\.(delete|batchDelete))
  • intentPattern — regex to match user intent text (optional)

These are produced by the compiler when it infers patterns. You can also edit the JSON directly for fine-grained control.


Approval Flow

When a tool needs approval:

  1. The agent attempts the tool.
  2. The plugin blocks it and returns a message with a request ID (UUID).
  3. You reply in chat: APPROVE <uuid> to allow once, or DENY <uuid> to block.
  4. If you approved, the agent can retry the same action; the approval is consumed.

Example:

Agent: I'll run `write` to save the file.
[Blocked] [Approval required] ask before file changes
Request ID: a1b2c3d4-...
Reply APPROVE a1b2c3d4-... to allow, or DENY a1b2c3d4-... to block.

You: APPROVE a1b2c3d4-...

Agent: [retries the write; it succeeds]

Path Protection

The plugin blocks the agent from modifying its own rules file. Writes to paths matching **/rules*.json or **/.config/ai-permissions-layer/** via write, edit, or apply_patch are blocked regardless of your rules.

This is enabled by default. Disable or customize via pathProtection in plugin config.


Configuration

Edit ~/.openclaw/openclaw.json under plugins.entries.ai-permissions-openclaw.config:

| Option | Default | Description | |--------|---------|--------------| | rulesPath | ~/.openclaw/ai-permissions-rules.json | Path to compiled rules JSON | | defaultWhenNoMatch | require_approval | When no rule matches: allow, require_approval, or block | | pathProtection.enabled | true | Block writes to rules file | | pathProtection.dangerousTools | ['write','edit','apply_patch'] | Tools that can write files (for path protection) |

Example:

{
  "plugins": {
    "entries": {
      "ai-permissions-openclaw": {
        "enabled": true,
        "config": {
          "rulesPath": "~/.openclaw/ai-permissions-rules.json",
          "defaultWhenNoMatch": "require_approval",
          "pathProtection": {
            "enabled": true
          }
        }
      }
    }
  }
}

Standalone Compile

Without OpenClaw, use the npm CLI:

# With OpenAI (requires OPENAI_API_KEY)
export OPENAI_API_KEY=your_key
npx ai-permissions-compile examples/rules.yaml ~/.openclaw/ai-permissions-rules.json

# With OpenClaw config (uses ~/.openclaw/.env and openclaw.json)
npx ai-permissions-compile --openclaw examples/rules.yaml ~/.openclaw/ai-permissions-rules.json

Format: One rule per line, each starting with -. See examples/rules.yaml.


Library Usage

npm install ai-permissions-layer
import { createMiddleware, match } from 'ai-permissions-layer';

const rules = [
  { action: 'block', tool: 'gmail.delete', reason: 'no delete' },
  { action: 'require_approval', tool: 'gmail.send', reason: 'ask first' },
  { action: 'allow', tool: 'read', reason: 'read-only ok' },
];

const middleware = createMiddleware(rules, executor, {
  defaultWhenNoMatch: 'require_approval',
  pathProtection: {},
});

const result = await middleware(
  { toolName: 'gmail.delete', args: {} },
  { text: 'delete emails' }
);
// result.decision === 'BLOCK', result.executed === false

Examples


License

GPL v3.