fix(firmware): OTA PSK cannot be provisioned — documented `provision.py --ota-psk` does not exist
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 94.4k
- Forks
- 12.5k
- Avg merge
- 21h 27m
- Merged PRs (30d)
- 43
Description
Summary
OTA firmware upload cannot be enabled on any node built from the shipped source, because the
only documented way to provision the device-side PSK does not exist.
main/ota_update.c:29-31 reads the pre-shared key from NVS namespace security, key
ota_psk. When it is empty, ota_check_auth() rejects every upload (fail-closed, RuView#596).
The comment at main/ota_update.c:39 tells the operator how to set it:
The OTA server still starts so the operator can
provision.py --ota-psk <hex>over USB-CDC
without a reflash, but the upload endpoint will reject every request until the PSK is set.
firmware/esp32-csi-node/provision.py has no --ota-psk argument, and contains no reference
to ota_psk or the security namespace at all — it generates only the csi_cfg namespace
(from provision.py:177). The only other ota_psk in the tree is in
v2/crates/wifi-densepose-desktop (src/domain/config.rs:26,
ui/src/pages/Settings.tsx:138), which is the client-side token the desktop app sends,
not something written to device NVS.
Net effect: OTA=ready in the boot log means only that the HTTP server started
(main/main.c:371, :504); authentication can never be satisfied through any shipped
workflow.
Why now
Observed while testing v0.8.4 on hardware. Nodes are otherwise healthy and streaming, but the
only non-USB update path is unusable, so every firmware change requires physical access.
Reproduction
On a node flashed from the published v0.8.4 assets and joined to WiFi:
$ curl -X POST --data-binary @esp32-csi-node-v0.8.4-8mb.bin \
-H 'Content-Type: application/octet-stream' \
http://<node-ip>:8032/ota
HTTP 403 after ~135 KB uploaded
Authentication required. Use: Authorization: Bearer <psk>
$ python3 provision.py --help | grep -c ota-psk
0
$ grep -c 'ota_psk\|security' provision.py
0
GET /ota/status on the same node responds normally, so the server is up:
{"version":"0.8.4","running_partition":"ota_0","next_partition":"ota_1","max_size":921600}
Done when
provision.pycan writesecurity/ota_pskto device NVS over USB-CDC without a reflash,
matching the behaviourota_update.c:39already documents; or- the firmware comment is corrected to name whatever the supported path actually is.
Work items
- Add
--ota-psk <hex>toprovision.py, emitting thesecuritynamespace alongside
csi_cfgin the generated NVS CSV. - Validate the value (the firmware caps it at
OTA_PSK_MAX_LEN65, hex-encoded SHA-256). - Decide whether the PSK belongs in the per-port state file — if so it needs the same
protection as the WiFi password (see the state-file permissions issue). - Consider making the boot log distinguish "OTA server started" from "OTA can accept
uploads", sinceOTA=readycurrently implies the latter.
Secondary, untested
/ota/status advertises max_size: 921600 while the shipped v0.8.4 image is 1,126,624 bytes
and ota_1 is 2,097,152 bytes. Whether that gate would reject a valid image could not be
tested, because the auth gate rejects first. Flagging only; it may be a stale constant.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with firmware/esp32-csi-node/provision.py and main/ota_update.c, comparing the existing csi_cfg NVS generation with the documented security/ota_psk path. Run provision.py --help and inspect the OTA PSK length constraint and state-file handling. Done means the supported workflow can provision the device-side PSK over USB-CDC without a reflash, or the firmware comment names the actual supported path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, python
- Domain
- embedded-iot, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100