Connect OpenClaw and NanoClaw to Contro1
Connect OpenClaw and NanoClaw assistants to Contro1: one command per computer, owner approval, approvals for commands, and company apps over MCP.
Connect an agent
Take NanoClaw from one admin DM to a team: credential use, package installs, MCP servers and new agents go to the right reviewer, with an owner and audit trail.
Updated Oct 25, 2026
NanoClaw already isolates agents in containers and holds risky changes for an admin. That works for one person. Contro1 makes it work for a company: the right reviewer decides, every agent group has an accountable owner, and every decision is on record.
Copy this skill link into your code agent to add NanoClaw and Contro1 to your system.
This page is about running NanoClaw for a team once it is connected: why a single admin DM stops working, how the connector binds each approval to the exact action, where approvals go, and what one connection turns on.
The setup steps, with every command and what you should see, are on one page: install the Contro1 CLI, connect each agent group, approve it as its owner, make Contro1 an approver, install the Contro1 channel, and check it with contro1 doctor nanoclaw.
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.
Start with the case, because it is the one that actually happens. You run an assistant in NanoClaw. You give it access to your mailbox, because you talk to it privately about work and you want it to read threads for you. That is exactly why you connected it.
A week later you add the same assistant to a group: a project with a client, a trip with friends, a channel with contractors. Somebody in that group types a message to it. It answers, and it has no way to know that the person asking is not you. It runs the action with its own authority, so the request from the group and the request from your private chat look identical to it. Anyone in that group can now ask it what is in your mailbox.
No permission was changed. Nothing was inherited. The assistant simply answered the room it was put in. This is the confused deputy problem, and it applies to any agent that more than one person can instruct while it holds standing access to one person's data. It is not a misconfiguration: it is what happens when the unit of authorization is the agent while the unit of exposure is the conversation.
Asking for approval on every action does not fix it. The approver sees "read the mailbox" and approves, because that is the workflow they set up. Without knowing which conversation asked, the approval adds friction and no safety.
Wire an agent to a new conversation and NanoClaw asks, in a direct message, whether to attach the main agent or deploy a dedicated one for that group. It is the right question, asked in the right place. It is also asked at the worst possible moment to answer it well.
A dedicated agent is the safe answer. It starts with nothing, so a group can ask it for nothing. Attaching the main agent is the answer that costs something, because the main agent is the one that has accumulated access: it is the one that reads your mail.
What makes the moment misleading is that the two decisions are weeks apart. You granted the mailbox in one context, deliberately, on a screen that said so. You are now on a phone, adding an assistant to a group about a trip, answering what reads as an operational detail. Nothing on that screen mentions the mailbox and nobody is thinking about it.
So Contro1 does not rely on you remembering. The connector re-reads which conversations the agent answers in, on a loop it already runs, from NanoClaw's own tables. Attach the main agent to a group and within a tick Contro1 knows it is reachable by people nobody named, and refuses it any personal account until its owner allows that by name. Nothing is polled: it reports only when the answer changed, so an agent sitting still costs no request at all.
The honest limit: this only ever tightens. Remove the agent from that group and Contro1 keeps treating it as shared until somebody runs contro1 connect again, because a claim of privacy arriving on an agent's own credential is exactly what must not be believed. The dangerous direction is fast and the harmless one waits, which is the right way round.
NanoClaw's approval card is a good design for one person running their own assistant. When a team or a company runs many agent groups, the same card creates new questions nobody can answer from a chat thread.
| Question | NanoClaw on its own | NanoClaw with Contro1 |
|---|---|---|
| Who approves a credential or a package install? | The first reachable admin or owner | The reviewer role you choose, with SLA and escalation |
| What if that person is asleep or on leave? | The card waits and expires | Routing and coverage send it to someone on shift |
| Who is accountable for each agent group? | Whoever holds the admin role | A named owner who approved the connection |
| Can an agent approve its own change? | No, the host holds the card | No, and the decision is also bound to the exact facts |
| What happened last month, and who allowed it? | Scattered chat history | One searchable audit trail across every group and host |
NanoClaw already holds sensitive operations for an admin, and that is a real control. It is worth knowing exactly what an approval there covers, whether or not you use Contro1.
An approval applies to the AGENT GROUP. A group answers in every conversation it is wired to, and sender_scope defaults to all, meaning it answers everyone in those conversations rather than a named list. So a credential approved once for a group is usable on behalf of whoever instructs that group next, including in a conversation added a week later, by someone who was never part of the decision. Nothing went wrong for this to happen. It is what group-level authorization means.
NanoClaw does ship controls for this: sender_scope known, agent_group_members, and unknown_sender_policy. They are off the fast path, so most installations never change them.
Contro1 does not make the grant finer. The unit is still the agent group, and we say so rather than implying otherwise. What changes is that the exposure is visible before the decision instead of after, that personal accounts are refused to a group-facing agent unless its owner allows it by name, that the decision reaches the accountable person rather than whoever holds the admin DM, and that there is a record to read afterwards.
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.
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 holds no Contro1 credential at all: it reads a mapping file and talks to the group's local Contro1 endpoint, and the key behind that endpoint belongs to the Contro1 service.
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.
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.
contro1 connect nanoclaw --agent <agent-group-id> takes the agent groups you name, shows what it is about to change, and asks the accountable owner to approve them. The owner sees a short code, every group by name, and what each one will be allowed to do. Nothing works before that approval.
It installs a small Contro1 service on the host that keeps a separate key for each agent group and serves each group its own local endpoint, then writes a mapping file for the channel, which the channel finds in its default place. Role changes inside NanoClaw always need a separate confirmation in a terminal, even with --yes.
1 · On the host
Takes the agent groups you name, previews the local changes and shows a short code.
2 · In Contro1
One screen: the code, each group by name, and what they can and cannot do.
3 · On the host
The Contro1 service keeps the keys; the channel only reads a per-group mapping.
Out of the box, NanoClaw delivers an approval card to an approver on the same chat platform the request came from, so a request made in WhatsApp would go to the owner's WhatsApp. The install includes one small change to NanoClaw's approval delivery: cards prefer the Contro1 approver when there is one. Unknown-sender and channel-registration cards stay where they are.
Inside Contro1, the request goes to the agent's reviewer. That is its accountable owner by default, and the owner can route it to anyone in the organization when approving the connection. Set CONTRO1_REQUIRED_ROLE to narrow review to one role.
| Approval | Where it goes |
|---|---|
| Credential use (OneCLI) | Contro1, to the agent's reviewer |
| Package installs (install_packages) | Contro1, to the agent's reviewer |
| New MCP servers (add_mcp_server) | Contro1, to the agent's reviewer |
| New agents (create_agent) | Contro1, to the agent's reviewer |
The MCP server grants nothing of its own. It is the Access page seen from wherever the call is coming from: the same grants, the same policy, the same refusals. Whoever is calling, not whoever is asking - an agent sees its own permissions, a coding assistant sees the permissions of the person who approved it.
Connecting is one thing, and it gives you two surfaces through the same credential: approval requests, and the Contro1 MCP server. They are not separate connections and there is no second key.
What the MCP server offers, though, depends on what the connection is allowed to do. An approvals-only connection carries requests:create, requests:read, requests:wait, requests:cancel_own and audit:write. The agent can identify itself, raise approval requests and write audit records. It has no invoke_action at all, so it cannot read a mailbox, and refusing to is the correct answer rather than a fault.
When the owner allows applications, the same connection gains actions:read, actions:preview, actions:execute, connections:read and skills:read. Same key, same endpoint, larger tool set. Nothing is reconnected and nothing is reissued.
That pattern is the whole design, and it holds for every caller. There is one MCP address, one tool catalog, and a gate that decides what each caller may reach: what changes between an agent on a connection and a person who has connected a coding assistant is not the endpoint or the list, it is the credential and therefore how far it may go. An agent acts as itself, with its own permissions. A coding assistant acts as the person who approved it, never with more than that person already has, and only if they approved running actions specifically. Neither can be widened by pointing at a different URL, because there is not one.
The third thing is the one people assume comes free with connecting, and it does not: on NanoClaw, a connection does not put Contro1 in the approval path. That also needs the Contro1 channel loaded into NanoClaw and Contro1 holding a role in the agent group. Until both are true the connection is live and no approval is ever routed, which is why contro1 doctor reports it under "Approvals reach Contro1" instead of leaving you to notice the silence.
Approvals cover what NanoClaw itself holds. To let a group's agents use company applications such as mail, calendar or tickets, give the group the Contro1 MCP server. Contro1 then decides which application actions each agent may use, asks a person where your policy says so, and records every call.
NanoClaw configures MCP servers per agent group, which fits one connection per group. Once the owner allows applications, contro1 apps enable nanoclaw --agent <agent-group-id> gives that group the Contro1 MCP server by its URL and keeps a credential for that one group in OneCLI, which adds it on the host. No credential is written anywhere the agent could read it, and a group can only ever act as itself.
Ask an agent to install a package, for example: install the npm package left-pad. Run ncl approvals list first: a row there is a real card, while an agent saying it sent one is not. A request titled NanoClaw: Install packages then appears in the Contro1 queue saying what will happen, with the packages as facts and the agent's reason shown as its own claim, including for a card picked up after a restart. 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.
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.
Two things. It adds a channel, the same extension point NanoClaw uses for Slack and Telegram: two files in src/channels and one import line. And it makes approval cards prefer the Contro1 approver, a few lines in NanoClaw's approval delivery, so requests made on any chat platform come to Contro1. Without a Contro1 approver, delivery behaves exactly as before.
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.
No, and neither does the channel. The key for each agent group is created on the host and kept by the Contro1 service. The channel only reads a mapping from group to local endpoint, and NanoClaw composes each container's environment explicitly, so nothing Contro1-related reaches a container.
NanoClaw's container isolation and host-held credentials are a strong base. What an enterprise adds is accountability: a named owner per agent group, approvals routed to the right role instead of one admin's DM, and an audit trail across every host. That is the layer this connector adds, with two small additions to NanoClaw's source (a channel and the approval delivery preference) and no fork.
Connect each agent group with contro1 connect nanoclaw --agent <agent-group-id>, confirm Contro1 as its approver, and set CONTRO1_REQUIRED_ROLE so approvals go to a reviewer role rather than one person. Every group then appears in Contro1 with its owner, and every decision is recorded. Connect OpenClaw and NanoClaw has every step.
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.
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.
NanoClaw v2.3.0, connector v0.2.4 and the contro1 CLI 0.2.29 or later. OneCLI 2.2.5 or later needs CLI v0.2.21 or later.
Connect OpenClaw and NanoClaw assistants to Contro1: one command per computer, owner approval, approvals for commands, and company apps over MCP.
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.
Learn how to create, inspect, and cancel Contro1 requests for approvals, clarifications, and escalations.
Use Contro1 audit records to log actions that agents are authorized to run autonomously, and correlation_id to connect requests and logs into one case timeline.