§8.5 — Cloud Relay Identity v1.5
RCAN messages can arrive via human operators, peer robots, or cloud functions. Without a sender_type field, the audit trail cannot distinguish autonomous cloud automation from human-initiated commands — a critical gap for incident investigation and consent enforcement.
The Problem
The Flutter → Cloud Functions → Firestore → robot bridge pipeline (the "castor bridge") allows Firebase Cloud Functions with no RURI to send commands to robots. These commands carry a human operator's JWT but are generated autonomously. Before v1.5:
- Audit records showed only the JWT
sub(user UUID), not the execution path - Consent requests from cloud functions appeared identical to human-originated requests
- A cloud function could generate consent requests that appeared to come from the human operator directly
sender_type Enum
All RCAN messages from this revision onward MUST include a sender_type field in the message envelope (see the live compatibility matrix for current revisions):
| Value | Meaning | Notes |
|---|---|---|
"human" | Command originated from a human operator directly | Default when field is absent (v1.4 compatibility) |
"robot" | Command sent by another RCAN robot (R2R) | Robot RURI in source field; delegation chain required |
"cloud_function" | Command generated by a cloud function or serverless runtime | MUST include cloud_provider field |
"system" | Internal system message (watchdog, scheduler, etc.) | No robot signing key available |
Additional Fields for Cloud Functions
When sender_type: "cloud_function", the message MUST also include:
{
"sender_type": "cloud_function",
"cloud_provider": "firebase", // "firebase" | "aws_lambda" | "gcp_run" | "azure_fn" | other
"function_name": "castor-bridge-v2", // Name/ID of the specific function
"function_region": "us-central1" // Optional: cloud region
} Why Cloud Functions Cannot Forge sender_type
A cloud function has no access to the robot's Ed25519 private key. Therefore:
- If the message is signed with the robot's key,
sender_typemust be"robot" - If the message carries a human JWT but no robot signature,
sender_typemust be"human"or"cloud_function" - A cloud function that sets
sender_type: "human"will be recorded with the JWT'ssubas the human — this is technically possible but dishonest, and creates operator accountability - The audit trail records
sender_typealongside the JWT subject — regulators and investigators can see the full chain
JWT Custom Claims for Cloud Functions
JWTs issued to cloud functions MUST include sender_type in the custom claims block:
{
"sub": "firebase-cloud-functions",
"aud": "rcan://rcan.dev/org/robot/v1/unit-001",
"scope": ["control"],
"sender_type": "cloud_function",
"cloud_provider": "firebase",
"exp": 1741003600
} Robots MUST reject service tokens that claim sender_type: "cloud_function" but have no cloud_provider field.
Consent Requests from Cloud Functions
When a CONSENT_REQUEST (type 20) arrives with sender_type: "cloud_function", the target robot's owner notification MUST display the cloud function identity prominently:
// Owner notification payload when sender_type == "cloud_function"
{
"title": "⚠️ Service Consent Request",
"body": "Firebase function 'castor-bridge-v2' (on behalf of Craig) is requesting\naccess to Robot B with scope: [control]",
"highlight": "cloud_function: castor-bridge-v2 via firebase"
}
// vs. normal human request
{
"title": "Consent Request",
"body": "Craig is requesting access to Robot B with scope: [control]"
} This prevents social engineering where a cloud function generates consent requests that appear to come from the human operator directly.
Audit Trail Requirements
CommitmentRecords MUST include:
sender_type— alwayscloud_providerandfunction_name— whensender_type == "cloud_function"- JWT
sub— the human or service identity authorizing the command
These fields cannot be modified after the commitment record is written (HMAC chain integrity).
rcan-py Usage
from rcan.message import RCANMessage
from rcan.types import SenderType
# Cloud function creating a command
msg = RCANMessage(
cmd="move_forward",
target="rcan://rcan.dev/org/robot/v1/unit-001",
sender_type=SenderType.CLOUD_FUNCTION,
cloud_provider="firebase",
function_name="castor-bridge-v2",
...
) See Also
- Consent Wire Protocol — consent request display rules
- Command Delegation Chain — robot-to-robot delegation (sender_type="robot")
- Message Type Reference — full envelope schema