Install
openclaw skills install scopeblind-passportSigned access control for your OpenClaw agent. Wraps MCP tool calls through protect-mcp to add per-tool policies, signed receipts, and trust tiers. Every action your agent takes produces a cryptographic receipt — independently verifiable by anyone, without trusting ScopeBlind.
openclaw skills install scopeblind-passportThis skill wraps your OpenClaw agent's MCP tool calls through protect-mcp, adding:
Any platform can log what its agents do. Very few will let you verify those logs without trusting them.
Use this skill when:
If you already have an OpenClaw config, generate a passported wrapper pack first:
npx @scopeblind/passport wrap --runtime openclaw --config ./openclaw.json --policy email-safe
That writes:
wrapped-config.jsonmanifest.jsonpassport.bundle.jsonprotect-mcp.jsonkeys/gateway.jsonVERIFY.mdCopy the mcpServers entries from wrapped-config.json into your OpenClaw config.
npx protect-mcp init
This creates:
keys/gateway.json — Ed25519 signing keypair (in current directory)protect-mcp.json — default shadow-mode policy (logs everything, blocks nothing)For each MCP server your agent uses, wrap it through protect-mcp. In your OpenClaw MCP config:
Before:
{
"mcpServers": {
"filesystem": {
"command": "node",
"args": ["filesystem-server.js"]
}
}
}
After:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["protect-mcp", "--policy", "protect-mcp.json", "--", "node", "filesystem-server.js"]
}
}
}
That's it. Every tool call now produces a signed receipt.
To move from shadow mode to enforce mode, copy a policy template and add --enforce:
# Copy a policy template
cp policies/email-safe.json protect-mcp.json
Then update your MCP config args to include --enforce:
"args": ["protect-mcp", "--policy", "protect-mcp.json", "--enforce", "--", "node", "server.js"]
See the policies/ directory for pre-built templates.
When the user asks you to perform these actions, execute them:
npx protect-mcp status
Display the output, which shows:
npx protect-mcp digest --today
Display the local summary, which includes:
npx protect-mcp receipts --last 20
Shows the 20 most recent decisions with tool name, decision, and timestamp.
When a tool call is blocked or rate-limited, explain:
When protect-mcp blocks a high-risk action that has require_approval: true in the policy, it returns:
REQUIRES_APPROVAL: The tool "send_email" requires human approval before execution.
Tell the user you need their approval to use "send_email" and will retry when granted.
Do NOT retry this tool call until the user explicitly approves it.
When you receive this response:
# For one-time approval (scoped to this specific request):
curl -s -X POST http://127.0.0.1:9876/approve -H 'Content-Type: application/json' -d '{"request_id":"REQUEST_ID","tool":"TOOL_NAME","mode":"once","nonce":"NONCE"}'
# For always-allow this tool (session-scoped, 24h TTL):
curl -s -X POST http://127.0.0.1:9876/approve -H 'Content-Type: application/json' -d '{"tool":"TOOL_NAME","mode":"always","nonce":"NONCE"}'
Replace REQUEST_ID, TOOL_NAME, and NONCE with the values from the REQUIRES_APPROVAL response.
When the user denies: Tell them the action was blocked and explain what was prevented.
curl -s http://127.0.0.1:9876/approvals
Pre-built policies are available in the policies/ directory:
| Pack | What it does |
|---|---|
shadow.json | Log everything, block nothing (default) |
web-browsing-safe.json | Rate-limit browsing, require approval for forms, block JS |
email-safe.json | Read freely, require approval to send, block delete |
strict.json | Block everything except reads (read-only mode) |
Every receipt is independently verifiable. The MIT-licensed verifier requires zero trust in ScopeBlind.
npx @veritasacta/verify --self-test
Receipts are available from the local HTTP status server while protect-mcp is running:
# Get the most recent receipt
curl -s http://127.0.0.1:9876/receipts/latest | jq -r '.receipt' > receipt.json
# Get all recent receipts
curl -s http://127.0.0.1:9876/receipts | jq -r '.receipts[0].receipt' > receipt.json
If the local status server is unavailable, use the persisted receipt file:
tail -n 1 .protect-mcp-receipts.jsonl > receipt.json
# Get the public key from status (shown under "Passport Identity")
npx protect-mcp status
# Verify with the public key
npx @veritasacta/verify receipt.json --key <public-key-hex>
The verifier checks Ed25519 signatures against public keys. No API calls, no accounts, no ScopeBlind servers involved.