Framework guides

NanoClaw human approval connector

Route NanoClaw admin approvals, credential use, package installs, MCP server changes and new agents, to Contro1 for a human decision, role routing and audit evidence, resolved through NanoClaw's own approval handler.

Updated Sep 15, 2026

NanoClaw already stops before an agent uses a credential or changes itself. The Contro1 channel makes Contro1 the approver: the right reviewer decides, the decision is bound to the exact action, and every outcome is recorded.

Use the integration skill

Copy this skill link into your code agent to add NanoClaw and Contro1 to your system.

Copy skill link

Key takeaways

  • NanoClaw runs each agent in its own container and asks an admin before credential use, package installs, MCP server changes and new agents. This connector makes Contro1 that admin.
  • It is a NanoClaw channel, installed like Slack or Telegram: two files and one import line. NanoClaw core is not patched.
  • NanoClaw still enforces its own rules on every decision: only the routed approver may resolve a card, a card resolves once, and an approved change is re-validated against current state.
  • Each request is bound to the facts NanoClaw recorded. The approval is re-read and re-hashed before the approve click; any change rejects it.
  • The Agent Credential stays in the host .env and is handed only to the contro1 CLI. Agent containers never see it.

What NanoClaw already gates

NanoClaw is a lightweight, open-source personal AI assistant that runs every agent in an isolated container and answers on WhatsApp, Telegram, Slack, Discord and other channels. Raw credentials stay outside the containers: agents reach APIs through the OneCLI gateway, which injects credentials on the host.

Some operations are held for an admin. When an agent needs a credential that requires approval, wants to install packages, add an MCP server or create another agent, NanoClaw does not run it. It sends an approval card to one admin's DM and applies the change only when that admin clicks Approve.

  • onecli_credential: an agent's call through the OneCLI gateway needs a credential that requires approval.
  • install_packages: an agent asks to add apt or npm packages to its container image.
  • add_mcp_server: an agent asks to add an MCP server to its configuration.
  • create_agent: an agent asks to create another agent.

How the connector works

The connector is a NanoClaw channel named contro1. You make its identity, contro1:approvals, the admin of the agent groups you want to govern. NanoClaw then routes their approval cards to it the same way it would to a person on Slack.

When a card arrives, the channel reads the approval row through NanoClaw's admin CLI, opens a Contro1 approval request, and polls for the decision. When a reviewer decides, the channel clicks the matching button back into NanoClaw. NanoClaw's own approval handler applies or declines the change and notifies the agent.

flow.txt
agent container   -- asks for install_packages -->  NanoClaw host
NanoClaw host     -- approval card ----------------> contro1 channel
contro1 channel   -- contro1 requests create ------> Contro1 queue --> reviewer
contro1 channel   <- decision (polled) ------------- Contro1
contro1 channel   -- approve | reject -------------> NanoClaw approval handler

Open the GitHub repo ยท Contro1 CLI

Why it cannot be bypassed from inside an agent

The decision never passes through the agent. The agent can only ask NanoClaw for an operation; the host holds the card, the approval row and the credential vault. The contro1 channel runs in the host process, and the Contro1 Agent Credential is read from the host .env with NanoClaw's own reader, which does not load values into the process environment. NanoClaw builds container environments explicitly, so the credential never reaches a container.

NanoClaw's safeguards stay in force underneath. A card can only be resolved by the approver it was routed to, so a click from anywhere else is ignored. Each approval resolves once. An approved self-modification re-enters NanoClaw's guard and is checked against current state before it applies.

  • The connector never writes to NanoClaw's database. It reads approvals with ncl and resolves them through the channel interface.
  • Only the contro1 CLI child process receives the credential, with a minimal environment.
  • The credential must be an agent-bound runtime credential. The CLI refuses a browser-issued login token and an organization-wide key before sending anything.

Bound to the exact action, fail closed

Each Contro1 request carries a sha256 binding over the facts NanoClaw recorded for the approval: the approval id, action, payload, agent group, session and title. Nothing an agent wrote about itself is part of it. Before clicking Approve, the channel re-reads the approval and recomputes the hash.

  • Denied, timed out or cancelled in Contro1: the approval is rejected in NanoClaw.
  • Approved, but the approval changed since the reviewer saw it: rejected, recorded as binding_mismatch.
  • Approved, but NanoClaw already expired or resolved it: nothing is clicked, recorded as expired.
  • NanoClaw times out the card first: the Contro1 request is cancelled.
  • Contro1 unreachable: nothing is clicked; the step retries and NanoClaw's own expiry stays the final word.

What to prepare in Contro1

Register an agent for the NanoClaw host, for example NanoClaw - home server, and create an Agent Credential for it under Settings > Agent credentials. The secret is shown once.

  • Scopes: requests:create, requests:read, requests:cancel_own and audit:write.
  • Decide who reviews NanoClaw approvals. Set CONTRO1_REQUIRED_ROLE to route every NanoClaw approval to one reviewer role, such as security.
  • Choose where reviewers see approvals: the Contro1 dashboard, Slack or Microsoft Teams.

Install the channel in NanoClaw

Run these steps in your NanoClaw checkout, or give the skill to the coding agent that maintains it. The contro1 CLI must be installed on the host.

terminal
# 1. Store the Agent Credential where only the NanoClaw service user can read it
sudo install -d -m 700 /etc/contro1
sudo sh -c 'umask 077; cat > /etc/contro1/nanoclaw-agent.token'   # paste, then Ctrl-D

# 2. Check it before wiring anything
CONTRO1_AGENT_TOKEN_FILE=/etc/contro1/nanoclaw-agent.token \
  contro1 bridge doctor --target nanoclaw --ncl ./bin/ncl

# 3. Copy the channel and register it
BASE=https://raw.githubusercontent.com/contro1-hq/contro1-nanoclaw-connector/main/nanoclaw/src/channels
curl -fsSL "$BASE/contro1.ts" -o src/channels/contro1.ts
curl -fsSL "$BASE/contro1-governance.ts" -o src/channels/contro1-governance.ts
echo "import './contro1.js';" >> src/channels/index.ts

# 4. Configure, build, restart the service
echo "CONTRO1_AGENT_TOKEN_FILE=/etc/contro1/nanoclaw-agent.token" >> .env
pnpm run build

# 5. Make Contro1 the approver for an agent group
ncl users create --id contro1:approvals --kind contro1 --display-name "Contro1 approvals"
ncl roles grant --user contro1:approvals --role admin --group <agent-group-id>

Which approvals reach Contro1

NanoClaw, not the connector, chooses the approver for every card, and the two approval types use different rules. Plan your roles with both in mind.

ApprovalWho NanoClaw routes it to
Credential use (OneCLI)The first reachable of: the agent group's admins, global admins, owners. With contro1:approvals as the group admin, these reach Contro1.
Self-modification (install_packages, add_mcp_server, create_agent)First an admin or owner on the same platform the request came from, then the same order as above. A human owner on the platform the agent was asked on receives the card instead of Contro1.

Verify it end to end

Ask an agent to install a package, for example: install the npm package left-pad. A request titled NanoClaw: Install packages appears in the Contro1 queue with the package list as machine-observed facts. Approve it: on the channel's next poll NanoClaw applies the change, rebuilding the agent image where packages require it, and tells the agent. Reject a second one, and the agent is told it was declined.

Event taxonomy

Every outcome is written as an audit record linked to its Contro1 request, so reviews and incident timelines show what was asked, who decided and what NanoClaw did.

events.txt
nanoclaw.approval.requested
nanoclaw.approval.approved
nanoclaw.approval.denied
nanoclaw.approval.timed_out
nanoclaw.approval.cancelled
nanoclaw.approval.expired
nanoclaw.approval.binding_mismatch
nanoclaw.approval.not_governed

Frequently asked questions

Does this patch NanoClaw?

No. It is a channel adapter, the extension point NanoClaw uses for Slack, Telegram and every other messaging platform. Installing it copies two files into src/channels and adds one import line. Removing it is the reverse.

What happens if Contro1 is unreachable?

Nothing is approved. The channel only clicks Approve after it has read an explicit approval from Contro1 and re-checked the binding. While Contro1 cannot be reached, approvals stay pending in NanoClaw and expire under NanoClaw's own rules.

Does the agent get the Contro1 credential?

No. The credential lives in the host .env, is read without being loaded into the process environment, and is passed only to the contro1 CLI child process. NanoClaw composes each container's environment explicitly, so it is never included.

What about a host restart with approvals open?

The channel keeps no state of its own. On startup it lists the open approvals routed to it and resumes them. Contro1 requests use a deterministic id, nanoclaw:<action>:<approval_id>, so resuming never creates a duplicate request.

Are unknown senders and channel registrations governed?

Not by this connector. NanoClaw handles those with separate flows, not admin approval rows. If such a card reaches the Contro1 approver it is recorded as nanoclaw.approval.not_governed and left for NanoClaw to expire.

Which versions is this built against?

NanoClaw v2.3.0 and the contro1 CLI 0.2.0 or later, which adds the runtime commands the channel uses.

Related resources

Contro1 CLI

Install and use the contro1 CLI to register AI agents, create approval requests, push AI inventory, retrieve evidence and traces, and test workflows before using the SDK or API.

OpenClaw human approval and audit connector

Give your OpenClaw personal AI assistant a real, unbypassable guardrail: signed human approval for sensitive actions, a durable audit of everything it does autonomously, and one review queue across many assistants.