Contro1 JavaScript and TypeScript SDK
Install and use @contro1/sdk in Node, TypeScript, Express, Fastify, or Next.js backends to create approval requests, verify webhooks, and write audit records.
Framework guides
Give Block Buzz agents human approvals, role-based routing, safe retries, and a complete audit trail before high-impact actions run.
Updated Aug 2, 2026
Connect a Buzz identity, choose which actions need review, and show the right person the exact action before it runs. Start in decision-only mode, then add the protected webhook executor when you want the connector to carry out approved actions.
Use the connector when a Buzz agent is about to change something outside Buzz: deploy a release, call a protected webhook, update a customer system, spend money, or perform another action that needs organizational control.
Buzz remains the workspace and signed identity layer. Contro1 supplies the agent record, reviewer routing, quorum, deadlines, callbacks, and evidence. The connector verifies the signed Buzz event, derives the action from event content, applies your policy, and stores the exact proposal.
Validation status: the automated test suite passes on Node.js 20 and 22. The connector stays experimental until we have run it end to end against a real Buzz relay and a real Contro1 organization, including callback delivery and recovery after a restart.
Buzz
Buzz signs the target and parameters so they cannot be replaced later.
Connector
The connector checks identity and chooses block, log, or human review.
Contro1
Contro1 routes the exact action by role, quorum, and deadline.
Connector
It continues only on an explicit approval, and only if the stored action still matches.
Outcome
Return the decision by default, or call the protected webhook you configured.
Run the connector on Node.js 20.19 or newer. You need a reachable Buzz relay, a connector Buzz key, a Contro1 organization API key, and a stable 32-byte envelope key for encrypted action envelopes.
Use CONTRO1_API_KEY from a scoped organization API key. A CLI token is a browser-issued credential tied to a human identity, has expiry and ownership filters, and cannot provide the persistent server identity this bridge needs.
The connector executable is contro1-buzz. These commands belong to the connector repository and do not add a buzz command to the existing contro1 CLI.
The stable connector identity key is the normalized relay origin plus the verified Buzz pubkey. The same pubkey on two relay origins intentionally creates two bindings and, by default, two claimed Contro1 agents.
Without --event, bind uses the configured connector key. With --event, it verifies the event ID and signature before binding the event actor. If NIP-OA is absent, the binding is owner_unverified; the connector never fabricates ownership.
Policy is connector-owned. Each rule can block an action, allow it with an audit record, or send it to Contro1 for review. Rules match action type, resource prefix, and environment. If you do not provide a policy file, the built-in default sends every action to review.
Write the action that will become the signed Buzz event content. action_id must identify the same proposed side effect across retries, such as workflow run plus step or tool-call ID. Do not derive it from retry time.
Do not add relay origin, event ID, or actor pubkey to this file. The sign command creates the event, and the connector derives those identity fields from the verified signed submission.
sign creates a Buzz event whose canonical content is the action file, then wraps it with the normalized relay origin. gate verifies that event and derives the proposal solely from its signed content.
Sign shortly before submission. By default, a new event may be up to 300 seconds old and 60 seconds ahead of the connector clock; both limits are configurable for a known queue delay.
The normal Buzz/ACP path is asynchronous. The bridge stores the gate and Contro1 request, returns pending, releases the channel turn, and continues waiting independently. Use --wait only for a dedicated CLI or CI process whose single job is to guard one action.
After restart, the server resumes durable gates that are still awaiting review. Query status by gate ID instead of asking the agent to resubmit the action.
POST /v1/gates accepts the same signed-action submission produced by contro1-buzz sign. The connector verifies the event before deriving its proposal. POST /v1/gates and GET /v1/gates/:id are connector-local routes protected by CONTRO1_BUZZ_INGRESS_TOKEN. POST /v1/callbacks/contro1 verifies Contro1 signature, timestamp, request ID, replay state, pending gate, and action binding.
These /v1 routes belong to the connector process you deploy and run inside your own network. They are not part of the Contro1 API.
The connector creates a normal Integration Protocol v1 approval request through createProtocolRequest(), the same call every other Contro1 integration uses.
Relay origin comes from the signed submission envelope. Event ID, actor pubkey, timestamp, and action content come from the verified event. Published @contro1/sdk 1.1.0 types expose action data as context.tool_name and context.tool_input, while verified Buzz facts live under metadata.machine_observed.
Those metadata facts are available in the dashboard/request record. Current Slack and Teams cards read context.machine_observed, which is not exposed by the published SDK 1.1.0 types, so those cards do not yet render the Buzz relay, event ID, actor key, attestation fingerprint, or action digest.
| Buzz or connector value | Contro1 field |
|---|---|
| Stable Contro1 binding | actor.agent_id |
| Buzz workflow and run | source.workflow_id and source.run_id |
| Action type and parameters | context.tool_name and context.tool_input |
| Resource and environment | context.resource and context.environment |
| Verified relay, event, pubkey, and digest | metadata.machine_observed |
| Customer policy result | policy_trigger and policy_context |
| Stable external action identity | external_request_id |
| Broader workflow or case | correlation_id |
A status of approved is never enough on its own. The connector requires an explicit decision_type of approve, or response.approved set to true, so a free-text reply can never be read as an approval.
In the default decision-only mode, a valid approval ends with state approved, disposition approved, and execution_status not_executed. The caller may continue using that action-bound decision. The callback path separately verifies HMAC freshness, request IDs, durable replay state, the pending gate, and the stored action digest.
Decision-only is the default because it separates the approval decision from destination access. If this connector should perform the side effect, webhook mode sends the exact stored action to one fixed HTTPS URL and signs the body with HMAC. Mock mode is only for an explicit demo.
| Mode | Configuration | Outcome |
|---|---|---|
| Decision only | CONTRO1_BUZZ_EXECUTION_MODE=decision-only | Returns approved with execution_status not_executed. Your trusted caller decides how to continue. |
| Webhook | Set mode=webhook, CONTRO1_BUZZ_EXECUTOR_URL, and CONTRO1_BUZZ_EXECUTOR_SECRET. | POSTs the stored action to one fixed HTTPS endpoint with an HMAC signature and records the external result. |
| Mock | CONTRO1_BUZZ_EXECUTION_MODE=mock | Records a harmless mock result for demos; it does not call a destination. |
| Surface | Verified baseline |
|---|---|
| Contro1 TypeScript SDK | @contro1/sdk 1.1.0 |
| Contro1 CLI | v0.1.4 plus commit 535adaa |
| Buzz source | 28ae6cd2174309529305724e455c7ca082f6fe4b |
| Node.js | Current Node.js 20 and 22 releases |
Not yet. The automated TypeScript, unit, integration, build, and Node.js 20/22 checks pass, but the live matrix against a real Buzz relay and Contro1 organization has not completed. Treat it as an integration preview until live callback, restart, and executor-idempotency scenarios pass.
No. The connector uses the existing /api/centcom/v1 runtime API through @contro1/sdk. The /v1/gates routes documented here are local to the connector server.
No. contro1-buzz is the executable shipped by the standalone connector repository. Existing Contro1 CLI commands remain unchanged.
Not by itself. The connector requires an explicit canonical approval decision and then verifies that the stored action, digest, gate state, and expiry still match.
No. Decision-only is the default and returns execution_status not_executed. Configure the fixed HTTPS webhook executor when the connector should perform the action, or choose mock mode explicitly for a harmless demo.
The connector is a persistent server process. Browser-issued CLI tokens are tied to a human login, expire, and apply ownership filters, so they are not an appropriate server identity.
Install and use @contro1/sdk in Node, TypeScript, Express, Fastify, or Next.js backends to create approval requests, verify webhooks, and write audit records.
Learn how to create, inspect, and cancel Contro1 requests for approvals, clarifications, and escalations.
Validate signed Contro1 callbacks and safely resume AI workflows after approvals, rejections, expirations, or 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.
Add business ownership, human approval, and audit evidence before Block Buzz agents deploy, send, spend, or change external systems.
Put a human approval in front of production deploys from Claude Code, Codex, local scripts, and GitHub Actions without confusing a convenience hook with an enforcement boundary.
A short practical guide for assigning an AI agent owner: who should be accountable, when a VP or department head should own it, and how to record fallback ownership.
Your ERP is the system of record for money and your CRM for customers. AI agents now take real business actions with no system of record at all. Here is what one must capture and how to stand it up fast.