Device security and robustness (openpanel C0): check code, pnc, lenient report
- POST /devices/pair answers a 2-character `check`, listed by /devices/pending and shown beside each waiting entry; five codes a minute per address, and at 50 waiting the oldest gives way instead of a 429 - portal-minted device tokens are asked for with the device's nonce (`pnc`) and held against it, so unpair and delete revoke them; one without `pnc` stands only while the nonce is 0 - a device credential acts as the device (`device_principal`), not as the approving superuser, so deleting that account unpairs nothing - the report is validated port by port: unknown enum values read as `unknown`, unreadable ports and sections are left out and logged, `config` may name an entry of `config_schemas`; 422 only for no schema 1 or no object - devices.json is parsed once per change (cached by stat), delete drops the report and keeps the nonce, a busy recheck runs in the background - scope and io only from enabled flows (start/stop tells the devices), a port bound twice gives one io row - the Devices tab's saves cancel and hold back device refetches until settled
This commit is contained in:
@@ -455,8 +455,9 @@ As a superuser:
|
||||
4. Open the pairing link on the device. It shows a six-character code.
|
||||
5. Enter that code under **Pairing**, check the device description, then press
|
||||
**Pair**. A device asking from your own network also appears in the list
|
||||
below, with what it says about itself, and **Pair this one** adopts it
|
||||
without the code.
|
||||
below, with what it says about itself and a two-character check. The device
|
||||
shows the same check beside its code. When the two match, **Pair this one**
|
||||
adopts it without the code.
|
||||
|
||||
The screen collects its credential and shows the assigned published dashboards.
|
||||
Several dashboards get a navigation rail. The page says whether the device is
|
||||
@@ -466,16 +467,22 @@ since the instance started.
|
||||
Each save carries the version it was read at. When someone else saved the
|
||||
device first, the save is refused and the page shows their version.
|
||||
|
||||
One address may ask for five codes a minute. At most 50 requests wait at once,
|
||||
and a new one pushes out the oldest.
|
||||
|
||||
A device credential reads its assigned dashboards, their bound messages and the
|
||||
artifacts they show. It writes only the targets of their controls and query
|
||||
charts, and the messages of its own `in` [ports](#the-devices-own-ports). A
|
||||
message its tiles only draw, or a dashboard setting is bound to, stays read
|
||||
only. On a locked dashboard only the query charts may still publish.
|
||||
|
||||
**Unpair screen** revokes a locally paired credential and keeps the device and
|
||||
its dashboards. Deleting the device removes the assignment and its access, and
|
||||
a device added again under the same name does not bring the old credential
|
||||
back.
|
||||
A device acts as itself and not as the superuser who paired it, so deleting or
|
||||
deactivating that account leaves the device paired.
|
||||
|
||||
**Unpair screen** revokes the device's credential and keeps the device and its
|
||||
dashboards. Deleting the device removes the assignment, its access and its
|
||||
report, and a device added again under the same name does not bring the old
|
||||
credential back.
|
||||
|
||||
The device definitions are stored in the flow repository (`_devices/<id>.json`),
|
||||
so their history is in git with the flows. The credential generation lives in
|
||||
@@ -517,8 +524,11 @@ ports it reports and what the published flows wire, each linked to its node.
|
||||
| type | The payload type, checked like any message's |
|
||||
| config | A JSON object passed to the device unread, such as `{"pull": "up", "debounce_ms": 50}` |
|
||||
|
||||
Only published flows count. A port wired in two of them, or a device node
|
||||
naming a device that does not exist, is an error on the canvas. Until a device
|
||||
Only enabled published flows count, so stopping a flow takes its ports out of
|
||||
the device's `io` and its credential's reach. A port wired in two of them, or a
|
||||
device node naming a device that does not exist, is an error on the canvas.
|
||||
Until it is fixed the device follows the first binding of the port, by message
|
||||
name. Until a device
|
||||
reports what it has, a port name is free text; once it has, a port it does not
|
||||
list is a warning and one wired the wrong way round, or to another type, an
|
||||
error. `int` and `float` pass for each other.
|
||||
@@ -537,8 +547,17 @@ Home, not a fault, since a panel switched off or asleep breaks nothing.
|
||||
|
||||
A paired device says what it has with `PUT /devices/{id}/report`, from its own
|
||||
credential only. openpanel sends it after pairing and once per boot. The report
|
||||
replaces the one before, is at most 16 KB and keys this version does not know
|
||||
are dropped:
|
||||
replaces the one before and is at most 16 KB. It is read leniently, so a newer
|
||||
firmware still reports to an older instance:
|
||||
|
||||
- keys this version does not know are dropped
|
||||
- a value it does not know for a display `shape` or a port `direction` reads as
|
||||
`unknown`, and a `features` value that is not true or false is left out
|
||||
- a port it cannot read, such as one with an unknown `dtype`, is left out on its
|
||||
own and named in the server log
|
||||
|
||||
Only a report that is not `schema` 1, or not an object at all, is refused with
|
||||
422.
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -558,9 +577,12 @@ are dropped:
|
||||
```
|
||||
|
||||
`config` is a JSON schema of the settings the device reads for that port, which
|
||||
the Device node turns into a form. `modes` lists the directions a port may be
|
||||
wired in when it may be either, as a GPIO pin. `on_demand` marks a port that
|
||||
sends only while somebody wants it.
|
||||
the Device node turns into a form. It may instead name an entry of a top-level
|
||||
`config_schemas` object, so pins that share a schema send it once:
|
||||
`"config_schemas": {"pin": {...}}` and `"config": "pin"` on each port. The
|
||||
schema is put in place when the report is read. `modes` lists the directions a
|
||||
port may be wired in when it may be either, as a GPIO pin. `on_demand` marks a
|
||||
port that sends only while somebody wants it.
|
||||
|
||||
The device's page shows the report under **Capabilities**, with each port's
|
||||
binding or **Use in flow** for it. A reported screen becomes a canvas preset in
|
||||
@@ -591,9 +613,11 @@ a request that came through it, or from outside your network, is adopted by
|
||||
its code only and never from the list.
|
||||
|
||||
The instance enforces the same dashboard and message limits. Remote
|
||||
credentials are issued by the portal, so **Unpair screen** does not revoke
|
||||
them; revoke them at the portal. Deleting the device removes access on the
|
||||
instance.
|
||||
credentials are issued by the portal with the device's credential generation
|
||||
in them, so **Unpair screen** and deleting the device revoke them as they do a
|
||||
local one. A credential from a portal older than this carries none and keeps
|
||||
working only while the device was never unpaired or deleted. Pair such a
|
||||
screen again once the portal is updated.
|
||||
|
||||
## See also
|
||||
|
||||
|
||||
Reference in New Issue
Block a user