Managing Devices
A device is an external client — a microcontroller, gateway, or script — that publishes telemetry to synapse over MQTT. Each device is registered under one Cell, gets its own credentials, and can be quarantined or revoked independently. This page covers the device lifecycle: register, connect, disable, rotate, delete.
Every registered device lives in the platform's device registry, which synapse reads to authenticate each connection.
Registering a device
With ribo
ribo sensor add <cell>
This registers a new device under the Cell and prints its credentials. The token is shown once — save it immediately.
ribo sensor add my-cell
# ✓ Registered device for my-cell
#
# device_id dev_a1b2c3d4
# token key_<64 hex chars>
# topic tissue/acct_9c3f21ab/dev_a1b2c3d4/<metric>
#
# Save the token now — it is not shown again.
# Connect over MQTT/TLS: username=dev_a1b2c3d4 password=<token>
With the dashboard
Open the dashboard, go to the Synapse section for your Cell, and click to register a device. The dashboard shows the device_id, token, and topic prefix — copy the token before you close the dialog.
The credential model
| Credential | Format | Role | Notes |
|---|---|---|---|
device_id |
dev_<8hex> |
MQTT username; the device's stable id | Never changes; safe to log and reference |
| token | key_<64hex> |
MQTT password | Shown once at register/rotate; stored only as a SHA-256 hash |
Synapse stores the token's SHA-256 hash, never the token itself, so a lost token cannot be recovered — only rotated. The auth type is token today (auth_type: "token").
Device lifecycle
Every operation below is available through ribo sensor (where a subcommand exists), the /v1/sensors/* REST API, and the MCP tools.
List
Every device registered to one Cell:
ribo sensor list my-cell
# DEVICE AUTH ENABLED
# dev_a1b2c3d4 token true
REST: GET /v1/sensors/{cell}/devices (one Cell) or GET /v1/sensors/devices (every device in the account).
Get
Fetch a single device's registry record (identity, auth type, enabled state, topic prefix). The token is never returned.
REST: GET /v1/sensors/{cell}/devices/{device_id}.
Enable / disable
Disabling a device flips its enabled flag to false; synapse then refuses the device's next MQTT CONNECT. The device_id, token hash, and any Cell-side reading history are all preserved.
Prefer disable over delete when you want to quarantine a noisy or possibly-compromised sensor temporarily — a disabled device can be re-enabled instantly, whereas a deleted device must be re-registered and gets a brand-new device_id and topic prefix.
REST: PATCH /v1/sensors/{cell}/devices/{device_id} with body {"enabled": false}.
Rotate token
Issue a new token for an existing device, keeping its device_id stable. The old token stops working immediately. Use this when a token leaks — it is strictly better than delete + re-register, because the device_id and topic prefix stay the same, so no other configuration changes. You only need to update the MQTT password on the device.
REST: POST /v1/sensors/{cell}/devices/{device_id}/rotate. The new token is returned once.
Delete
Revoke a device entirely. Its credentials stop working immediately and its registry row is removed.
ribo sensor delete my-cell dev_a1b2c3d4
# ✓ Deleted device dev_a1b2c3d4
REST: DELETE /v1/sensors/{cell}/devices/{device_id}.
The
ribo sensorcommand currently exposesadd,list, anddelete. Enable/disable and rotate are available through the REST API and the MCP tools.
Connecting an MQTT client
Any standard MQTT 3.1.1 client works. Point it at ingest.tissue.dev:8883 over TLS, authenticate with the device_id/token, and publish to your device topic.
Using the mosquitto_pub CLI:
mosquitto_pub \
-h ingest.tissue.dev -p 8883 --tls-use-os-certs \
-u dev_a1b2c3d4 \
-P key_<64 hex chars> \
-t 'tissue/acct_9c3f21ab/dev_a1b2c3d4/temperature' \
-m '{"value":21.4,"unit":"C"}'
(--tls-use-os-certs validates against your system's trusted CAs — same flag on macOS, Linux, and Windows. On mosquitto older than 2.0.11, pass --cafile /etc/ssl/cert.pem (macOS) or --cafile /etc/ssl/certs/ca-certificates.crt (Linux) instead.)
The topic must be inside the device's own namespace (tissue/<account>/<device>/) — synapse rejects any publish outside it.
Rate limits and payload size
Synapse applies token-bucket rate limits and a maximum payload size. These are the platform defaults (operators can tune them per edge):
| Limit | Default | Notes |
|---|---|---|
| Per-device rate | 10 messages/sec | Sustained; token-bucket refill |
| Per-device burst | 40 messages | Bucket capacity |
| Per-account rate | 100 messages/sec | Sustained, across all the account's devices |
| Per-account burst | 400 messages | Bucket capacity |
| Max payload | 65536 bytes (64 KiB) | Larger messages are rejected |
Over-rate messages are dropped, not queued — telemetry is loss-tolerant, so a flooding device is shed cheaply before it ever touches the registry or your Cell.
See also
- Synapse Overview — how ingest works end to end
- Sensor API Reference — the
/v1/sensors/*endpoints - ribo CLI Reference —
ribo sensorcommands