Documentation

Everything you need to secure your AI agent with passkey approvals.

Overview — How ClawGate Works

ClawGate adds human-in-the-loop approval to AI agent workflows using passkeys (Face ID / Touch ID). When your agent tries to do something sensitive — delete files, send emails, publish packages — ClawGate intercepts the action, sends a push notification to your phone, and waits for your biometric approval before proceeding.

The Three Components

📱

iOS App

Your control panel. Register passkeys, manage API keys, approve/deny actions with Face ID. Get push notifications even when the app is closed.

🖥️

ClawGate Server

Handles approval requests, WebAuthn verification, push notifications. Hosted at api.clawgate.ai or self-host your own.

🔌

OpenClaw Plugin

Intercepts tool calls at the infrastructure level. Pattern-matches commands. Agents cannot bypass it.

ClawGate follows the delegation pattern: your agent requests approval for specific actions, you approve with your passkey, and the agent receives a scoped, time-limited token. The agent never has access to your passkey — same model as OAuth 2.0.


End-to-End Flow

Here's exactly what happens when your agent hits a sensitive command:

1

Agent Makes a Tool Call

Your agent decides to run rm -rf ./old-data or npm publish. This goes through OpenClaw's tool execution pipeline.

2

ClawGate Plugin Intercepts

The plugin's before_tool_call hook fires. It checks the command against your configured patterns. Match found → approval required.

3

Approval Request Created

Plugin sends a POST to the ClawGate server with the action details, agent ID, and context. The server creates a pending approval request.

4

Push Notification Sent

The server sends an APNs push notification to your registered iOS device. You see the action description and can tap to open the app.

5

You Approve with Face ID

Open the notification, review the action, and approve (or deny) with Face ID. The passkey authenticates your decision via WebAuthn — phishing-resistant by design.

6

Agent Proceeds (or Stops)

The plugin polls for the result. Approved → tool call executes normally. Denied or timed out → tool call is blocked and the agent gets a denial message.

# Real example: agent tries to delete files
Agent → exec: Remove-Item -Recurse ./old-backups
🦞🔐 ClawGate: intercepted exec — requesting approval...
# Push notification → iPhone → Face ID scan
✅ ClawGate: exec approved (req_a8f3k2)
Agent → "Done, old backups removed."

Quick Start

1. Download the ClawGate iOS App

Get ClawGate from the App Store. Create your account with email, then register your passkey — just one Face ID scan. Your passkey syncs via iCloud Keychain across all your Apple devices.

2. Generate an API Key

In the app: Settings → API Keys → Create New. Name it (e.g. "My Agent") and copy the key. It looks like ag_xDWZ7V_OamQEDz-uBk5t4LeM6bZxBHXi. You won't see it again, but you can always generate a new one.

3. Install the OpenClaw Plugin

# Via OpenClaw CLI (recommended)
openclaw plugins install clawgate

# Or manually
mkdir -p ~/.openclaw/extensions/clawgate
cd ~/.openclaw/extensions/clawgate
npm install clawgate

4. Add to Your OpenClaw Config

Edit ~/.openclaw/openclaw.json:

{
  "plugins": {
    "entries": {
      "clawgate": {
        "enabled": true,
        "config": {
          "apiKey": "ag_YOUR_KEY_HERE",
          "agentId": "my-agent"
        }
      }
    }
  }
}

The server defaults to https://api.clawgate.ai. Only change it if you're self-hosting.

5. Restart and Test

openclaw gateway restart
openclaw clawgate status   # verify connection
openclaw clawgate test     # send test approval to your phone

Approve the test notification with Face ID. Then try asking your agent to delete a test file — you'll see ClawGate intercept it in real time.

🎉

That's it. ClawGate is now enforcing approval on sensitive commands at the infrastructure level. Your agent can't bypass it.


Configuring Patterns

Patterns determine which tool calls require approval. They use regular expressions (case-insensitive) and can be scoped to specific tools.

Default Patterns

ClawGate ships with sensible defaults that catch dangerous operations:

PatternDescriptionTools
rm\sDelete files (Unix)exec
rm -rfRecursive deleteexec
del\sDelete files (Windows)exec
Remove-ItemDelete files (PowerShell)exec
Format-VolumeFormat disk volumeexec
Clear-DiskClear diskexec
Stop-ServiceStop Windows serviceexec
npm publishPublish to npmexec
git push.*--forceForce pushexec
drop.*tableDrop database tableexec
truncateTruncate tableexec
send.*emailSend emailexec

Custom Patterns

Override or extend patterns in your config:

"config": {
  "apiKey": "ag_YOUR_KEY",
  "agentId": "my-agent",
  "patterns": [
    { "match": "rm\\s", "description": "Delete files", "tools": ["exec"] },
    { "match": "stripe.*charge", "description": "Stripe charge", "tools": ["exec"] },
    { "match": "curl.*POST", "description": "HTTP POST", "tools": ["exec"] },
    { "match": "send.*email", "description": "Send email" }
  ]
}

Pattern fields:

  • match — Regex pattern (case-insensitive)
  • description — Shown in the push notification
  • tools — Limit to specific tool names (e.g. ["exec"]). Omit to match all tools.
  • scopes — Optional scopes attached to the approval token

Always-Approve Tools

Require approval for every call to a specific tool, regardless of pattern:

"alwaysRequireApproval": ["message", "browser"]

All Configuration Options

OptionDefaultDescription
serverUrlhttps://api.clawgate.aiClawGate server URL
apiKeyrequiredAPI key from the ClawGate app
agentIdopenclawIdentifier for this agent (shown in approvals)
timeoutSeconds120How long to wait for approval
blockOnTimeouttrueBlock action if approval times out
blockOnErrortrueBlock if server unreachable (fail-closed)
pollIntervalMs2000Polling interval for approval status
patterns12 defaultsArray of sensitive patterns
alwaysRequireApproval[]Tool names that always need approval

💡 Fail-closed by default: If the ClawGate server is unreachable or a request times out, the action is blocked. Set blockOnError: false or blockOnTimeout: false to change this behavior (not recommended for production).


CLI Commands

openclaw clawgate status

Shows server connection, agent ID, pattern count, fail-closed mode.

openclaw clawgate test

Sends a test approval request to your phone. Use to verify Face ID flow works end-to-end.

openclaw clawgate patterns

Lists all active patterns with their regex and tool scope.


Security Model

🔒 Infrastructure-level enforcement

ClawGate uses OpenClaw's before_tool_call hook. This runs before any tool executes. The agent cannot skip, override, or work around it — it's enforced by the platform, not the agent.

🛡️ Phishing-resistant passkeys

Passkeys (WebAuthn/FIDO2) are bound to the registered domain. They can't be phished, replayed, or extracted. Even if an attacker compromises the agent, they can't approve actions without your biometric.

⏱️ Scoped, time-limited tokens

Approved actions receive a JWT token that's scoped to the specific action and expires in minutes. Can't be reused for different actions.

🚫 Fail-closed

If the server is unreachable, push fails, or the request times out — the action is blocked. Security degrades gracefully toward "deny" rather than "allow".

📊 Full audit trail

Every approval request is logged: what action, which agent, when it was requested, and whether it was approved, denied, or timed out. Viewable in the iOS app.

Why not just use passwords or OTPs?

FeaturePasskeysPasswordsOTPs
Phishing-resistant
Nothing to remember
Fast (< 2 seconds)
Can't be shared/stolen

API Reference

Use the API to integrate ClawGate with any agent framework — not just OpenClaw. Full reference: API.md on GitHub

Request Approval

POST https://api.clawgate.ai/api/v1/approval/request
Authorization: Bearer ag_your_api_key
Content-Type: application/json

{
  "agentId": "my-agent",
  "action": "send-email",
  "description": "Send quarterly report to investors@company.com",
  "timeoutSeconds": 120,
  "scopes": ["email:send"]
}

// Response:
{
  "requestId": "req_abc123",
  "status": "pending",
  "expiresAt": "2026-02-11T18:05:00Z"
}

Poll for Status

GET https://api.clawgate.ai/api/v1/approval/status/{requestId}
Authorization: Bearer ag_your_api_key

// Response (approved):
{
  "requestId": "req_abc123",
  "status": "APPROVED",
  "token": "eyJhbGciOiJFUzI1NiIs...",
  "tokenExpiresAt": "2026-02-11T18:08:00Z"
}

// Possible statuses: PENDING, APPROVED, DENIED, EXPIRED

Integration Example (Python)

import requests, time

API_KEY = "ag_your_key"
BASE = "https://api.clawgate.ai/api/v1"

def request_approval(action, description):
    r = requests.post(f"{BASE}/approval/request",
        headers={"Authorization": f"Bearer {API_KEY}"},
        json={"agentId": "my-agent", "action": action, "description": description}
    )
    req_id = r.json()["requestId"]
    
    for _ in range(60):  # poll for 2 minutes
        s = requests.get(f"{BASE}/approval/status/{req_id}",
            headers={"Authorization": f"Bearer {API_KEY}"}
        ).json()
        if s["status"] == "APPROVED": return True
        if s["status"] in ("DENIED", "EXPIRED"): return False
        time.sleep(2)
    return False

if request_approval("send-email", "Send report to investors@co.com"):
    send_the_email()
else:
    print("Denied by user")

Self-Hosting

ClawGate is 100% open source. Self-host everything if you want full control.

Requirements

  • Node.js 20+
  • PostgreSQL 14+ (or SQLite for development)
  • HTTPS domain (required for WebAuthn)
  • Apple Developer account (for push notifications)

Docker

git clone https://github.com/AsteyaTech-com/clawgate-api.git
cd clawgate-api
docker-compose up -d

Manual

git clone https://github.com/AsteyaTech-com/clawgate-api.git
cd clawgate-api/server
npm install
cp .env.example .env    # edit with your DB, keys, etc.
npx prisma db push
npm run dev

Then set serverUrl in your plugin config to your server's URL. Full guide: GETTING_STARTED.md


Troubleshooting

Plugin says "missing apiKey — skipping"

Check that your openclaw.json has the correct path: plugins.entries.clawgate.config.apiKey. Restart the gateway after editing.

Not getting push notifications

Make sure notifications are enabled for ClawGate in iOS Settings → Notifications. Also check that your device token was registered — open the app and it should re-register automatically.

"Server unreachable — blocked" but server is up

Check your network/firewall. The plugin needs to reach api.clawgate.ai on port 443. Run openclaw clawgate status to test connectivity.

Too many false positives (dev commands getting blocked)

Override the default patterns with more specific ones. For example, instead of matching all Remove-Item, match only Remove-Item.*-Recurse or specific paths.

Approval timed out but I never saw a notification

Push delivery isn't guaranteed — APNs can delay or drop notifications. If this happens frequently, check the ClawGate app for pending requests (they appear even without push).

Need help? Open an issue on GitHub or check the setup guide.