Onboarding a Device
Onboarding is how a physical device becomes a trusted source of data in your account: it gets an identity, a credential, and a Cell that receives its readings. This page explains the flow and the security model behind it — what a device can and cannot do once it's connected.
There are two ways in:
| Path | For | How |
|---|---|---|
| Pre-provisioned device (e.g. a tissue Sense demo/workshop device) | Devices that ship ready to go, with a QR sticker | Scan the QR, create your account, power on — the device links itself. No commands, no credentials to copy. |
| Bring your own device | Any board or program that speaks MQTT over TLS | Register it under a Cell, put the credentials on the device, publish. See Connect Your Own Device. |
Both paths end in exactly the same place: a registered device with its own
credential, publishing into its own topic namespace, dispatched to your Cell's
sensor() handler.
Pre-provisioned devices (QR onboarding)
A pre-provisioned device — like the tissue Sense boards handed out at workshops — is registered before you ever touch it. Its identity is recorded at build time, and the QR sticker on the case ties that identity to whoever scans it:
- Scan the QR code. It opens the setup page for this specific device. Create your free account there (or sign in). Each device's QR link belongs to its owner — accounts are never shared.
- Power the device and give it Wi-Fi. The device opens a temporary Wi-Fi network with a captive portal where you pick your home network.
- The device links itself. Once online, it contacts the setup endpoint, which recognizes it and hands back its reporting credentials — directly to the device, over TLS. The credentials are stored in the device's own flash; you never see or type them.
From that moment the device is indistinguishable from one you provisioned by hand: same credential model, same isolation, same lifecycle controls below.
The claim step is deliberately narrow: the endpoint only links devices that were pre-registered, it hands out a device's credentials only once (a second claim requires a factory reset of the device), and it is rate-limited against guessing.
Bring your own device
If you're bringing your own hardware, provisioning is explicit and takes one command — register the device under the Cell that should receive its data:
ribo sensor add my-sensors
# device_id dev_a1b2c3d4 ← MQTT username
# token key_<64 hex> ← MQTT password — shown once, save it now
# topic tissue/<account>/<device>/<metric>
Then point any MQTT 3.1.1 client at ingest.tissue.dev:8883 (TLS) with those
credentials. The full walkthrough — including MicroPython examples and
flashing instructions — is Connect Your Own Device.
The security environment
The design goal: compromising one device compromises that one device's data stream, and nothing else. Concretely:
One device, one key
Every device gets its own credential at registration — a stable device_id
(the MQTT username) and a random 256-bit token (the password). Register each
physical board separately; don't share a token across devices. A leaked token
then exposes only that board's stream, and you can revoke it without touching
the rest of your fleet.
Tokens are never stored — only their hashes
The platform keeps a SHA-256 hash of each token, never the token itself, and comparisons are constant-time. A token is shown exactly once, at registration (or rotation). If it's lost, it cannot be recovered — only rotated. If the registry were ever exposed, no device credentials would leak with it.
Every connection is authenticated and encrypted
Devices connect over TLS to ingest.tissue.dev:8883. The broker verifies the
device_id + token pair on every MQTT CONNECT, and a disabled device is
refused at the door.
Devices are boxed into their own topic namespace
Each device may publish only inside its own prefix —
tissue/<account>/<device>/… — and this is enforced by the broker, not by
convention. A device cannot publish into another device's stream (even within
the same account), cannot subscribe to other devices' topics, and cannot
impersonate anyone: the topic itself carries the identity that was
authenticated.
Quarantine, rotate, revoke — per device
Each device can be managed independently, with no effect on the others:
- Disable — instantly refuses the device's next connection; its history and identity are preserved, and it can be re-enabled just as instantly. Use this to quarantine a suspicious or misbehaving sensor.
- Rotate — mints a new token for the same
device_id. The old token stops working immediately; nothing else about the device changes. - Delete — removes the device entirely; its credentials stop working immediately.
All three are available from the dashboard, the
REST API, and (add/list/delete) the ribo sensor CLI —
see Managing Devices.
Flood protection and reporting cadence
Two layers of rate limiting protect the platform and your account:
- Abuse caps: at most 10 messages/second per device (burst 40) and 100 messages/second per account (burst 400), with a 64 KiB payload cap. Over-rate messages are dropped, not queued — a runaway device is shed cheaply and can't starve the rest of your account.
- Telemetry cadence: the supported reporting rate is one reading per minute per metric (per device). Faster readings are dropped server-side — design your firmware to report each metric at most once a minute. (Demo and specially provisioned accounts may run at higher cadences; if your application genuinely needs faster telemetry, get in touch.)
Cloud-to-device commands can't loop back
Downlink messages (commands your Cell sends to a device via its cmd/…
topics) require the device's own credential, are confined to that device's
namespace, and are never dispatched back into your Cell's sensor() handler —
so a command can't masquerade as a reading or create a feedback loop.
After onboarding
- Readings arrive in your Cell's
sensor(event, env)handler — see the Synapse Overview for the event shape and a full example Cell. - Manage the device's lifecycle in Managing Devices.
- Automate provisioning with the Sensor API or the MCP server if an AI agent is doing the work.