RCAN v1.5: Making Robot-to-Robot Communication Production-Safe
Six weeks ago I wrote about how I got my two robots to talk to each other. Today, the protocol they were speaking just got significantly safer.
RCAN v1.5 shipped today across all five ecosystem repos simultaneously. Here’s what changed and why it matters.
The audit that started it all
Before shipping Bob and Alex’s live conversation to the world, I commissioned a comprehensive protocol audit — a fresh-eyes review of every communication scenario the ecosystem needed to handle: human↔robot, robot↔robot, cloud relay, offline operation, multi-party consent, and more.
The audit found 22 gaps. Twelve were rated CRITICAL or HIGH. Several were deployment blockers for any safety-critical environment.
The most concerning:
No replay attack window. A captured signed command was valid forever. An attacker with passive network access could replay a move_forward command indefinitely. The msg_id field existed but receivers weren’t required to track it.
No robot identity revocation. A stolen robot retained full cryptographic identity. Its peers continued trusting it. In a 50-robot factory, one compromised unit could command the others indefinitely.
Consent was implemented but not spec’d. The ConsentManager existed in OpenCastor, but there was no on-wire RCAN format. Two different runtimes couldn’t exchange consent messages.
Offline auth was broken by design. JWT validation required registry connectivity. A robot that lost internet couldn’t authenticate anyone — even its own owner trying to ESTOP it.
What v1.5 fixes
18 of 22 gaps addressed in this release. The highlights:
Replay attack prevention (GAP-03)
Every RCAN message now carries a msg_id that receivers MUST track in a sliding-window seen-set. Default window: 30 seconds. Safety messages (ESTOP, RESUME): 10 seconds max. Duplicate msg_id within the window → rejected before signature verification (prevents DoS via replay storms).
Robot identity revocation (GAP-02)
Registries now expose GET /api/v1/robots/{rrn}/revocation-status. A new ROBOT_REVOCATION message type broadcasts invalidations to all reachable peers. Peers cache revocation status with a 1-hour TTL. Offline robots get a 3600-second grace period before entering quarantine. ESTOP from a revoked robot still works — you still need to stop it.
Command delegation chains (GAP-01)
When Robot A commands Robot B on behalf of Human A, the delegation_chain array proves it. Each hop is signed by the forwarding principal. Receivers verify every signature. Max 4 hops. Chain depth exceeded → DELEGATION_CHAIN_EXCEEDED. The audit trail now shows the full human provenance of every command.
Consent wire protocol (GAP-05)
CONSENT_REQUEST (type 20), CONSENT_GRANT (21), CONSENT_DENY (22) now have a fully specified on-wire format with required fields, JSON schema, and a defined 7-step sequence. Two different RCAN implementations can now exchange consent messages interoperably.
Training data consent (GAP-10)
New TRAINING_CONSENT_REQUEST/GRANT/DENY message types. DataCategory enum covers VIDEO, AUDIO, LOCATION, BIOMETRIC, TELEMETRY. Consent records carry eu_ai_act_article references. This addresses EU AI Act Article 10 (training data governance) — with the August 2, 2026 deadline in mind.
ESTOP QoS (GAP-11)
Three delivery levels: fire-and-forget (0), acknowledged (1), exactly-once (2). ESTOP is now required to use QoS level 2. The sender retries until it receives an ACK. This closes the gap where a network hiccup could cause a safety-critical command to be silently dropped.
Offline operation (GAP-06)
Robots entering offline mode (registry unreachable for 300s) switch to a restricted mode: same-network same-owner commands only. ESTOP always accepted. Cross-registry consent blocked. On reconnection, all cached principals are re-authenticated.
Cloud relay identity (GAP-08)
New sender_type enum: robot | human | cloud_function | system. Cloud Functions (like our sendCommand relay) MUST set sender_type: cloud_function with a cloud_provider field. The audit trail now records who relayed every command — you can always tell if a command came from a human, a robot, or cloud infrastructure.
The numbers
- rcan-spec v1.5: 10 new pages, 31 message types (up from 19)
- rcan-py v0.5.0: 12 new modules, 430 tests (287 → 430)
- rcan-ts v0.5.0: 10 new modules, 311 tests (205 → 311)
- OpenCastor v2026.3.17.0: replay cache, ESTOP QoS, offline mode, sender type audit
- RRF v1.5.0: revocation API, key history, RCAN v1.5 robot fields
- OpenCastor Fleet UI: consent request screens, revocation badges, v1.5 status chips
All shipped in one coordinated day, all tests passing.
What’s deferred to v1.6
Four gaps didn’t make v1.5: federated consent (cross-registry permissions — needs multi-org trust anchor design), bandwidth-constrained transports (BLE/LoRa/SMS — 10+ page spec), multi-modal payloads (binary framing for image/audio in RCAN messages), and human identity verification (cryptographic proof that the human is who they claim).
None of these are safety-critical blockers. They’re next.
Try it
# Runtime
pip install opencastor==2026.3.17.0
# Python SDK
pip install rcan==0.5.0
# TypeScript SDK
npm install @continuonai/[email protected]
# Spec
# https://rcan.dev/spec/
The fleet UI is live at app.opencastor.com — sign in with Google to see your robots.
Bob and Alex are running v1.5 right now. Their conversations now have replay protection, delegation chains, and proper cloud relay attribution. Feels more real.
Full spec: rcan.dev/spec · OpenCastor changelog · GitHub