approve_node never rotates an existing key; node update-check endpoint; real Update Node button (node-26#14, #15) #194

Merged
logan merged 1 commits from fix/node-14-15-update-endpoint into main 2026-10-04 01:17:32 -04:00
Owner

Server half of node-26#14 and node-26#15. Pairs with node-26 PR fix/14-15-provision-ota. Merging deploys to prod. The owner decides when.

  • approve_node reuses node_keys/{id}.api_key when one already exists. It still re-syncs dynsec with that same key and never overwrites node_keys, so re-clicking Approve can no longer lock out a live node. Rotating a key stays a separate action (reissue-key).
  • POST /nodes/{id}/request-update (admin only) sets update_requested_at on the node doc and also sends the MQTT node_update command (best-effort).
  • POST /nodes/{id}/update-check is the host updater's HTTPS check-in. Auth is checked inline: a Bearer api_key for that node, or X-Pickup-Secret. It returns only update_requested_at and records updater_last_check_at, the sha and the applied result. An unknown node gets 401 rather than 404, so the endpoint can't be used to discover node IDs. C2 cannot name a ref, an image or a command.
  • Frontend: a new admin-only "Update Node Software" button calls request-update and has accurate confirm text. The node page now shows the updater check-in time and the last update's state.

Tests: c2-core 509 pass, including the new tests/test_node_provisioning.py (12 tests). Frontend typecheck has not run because there's no node/npm on the authoring box. Please run npm run typecheck in drb-frontend/ before merging.

Server half of node-26#14 and node-26#15. Pairs with node-26 PR `fix/14-15-provision-ota`. **Merging deploys to prod. The owner decides when.** - **approve_node** reuses `node_keys/{id}.api_key` when one already exists. It still re-syncs dynsec with that same key and never overwrites `node_keys`, so re-clicking Approve can no longer lock out a live node. Rotating a key stays a separate action (`reissue-key`). - **POST /nodes/{id}/request-update** (admin only) sets `update_requested_at` on the node doc and also sends the MQTT `node_update` command (best-effort). - **POST /nodes/{id}/update-check** is the host updater's HTTPS check-in. Auth is checked inline: a Bearer api_key for *that* node, or `X-Pickup-Secret`. It returns only `update_requested_at` and records `updater_last_check_at`, the sha and the applied result. An unknown node gets 401 rather than 404, so the endpoint can't be used to discover node IDs. C2 cannot name a ref, an image or a command. - **Frontend:** a new admin-only "Update Node Software" button calls request-update and has accurate confirm text. The node page now shows the updater check-in time and the last update's state. **Tests:** c2-core 509 pass, including the new `tests/test_node_provisioning.py` (12 tests). **Frontend typecheck has not run** because there's no node/npm on the authoring box. Please run `npm run typecheck` in `drb-frontend/` before merging.
logan added 1 commit 2026-10-04 01:11:25 -04:00
- approve_node: reuses node_keys/{id}.api_key when one exists (still
  re-syncs dynsec with it, still never overwrites node_keys). Re-clicking
  Approve can no longer lock a live node out. Reissue stays explicit.
- POST /nodes/{id}/request-update (admin): sets update_requested_at on the
  node doc AND sends MQTT node_update best-effort, so offline/locked-out
  nodes still get it.
- POST /nodes/{id}/update-check (node, inline auth: Bearer api_key for THAT
  node or X-Pickup-Secret): host updater's HTTPS check-in. Returns only
  update_requested_at; records updater_last_check_at / sha / applied result.
  Unknown node -> 401 (no node_id oracle). C2 cannot name a ref, image or
  command.
- Frontend: "Update Node Software" (admin only) calls request-update, honest
  confirm text; node page shows updater check-in and last update state.

Tests: tests/test_node_provisioning.py (12).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
logan merged commit ae0ece9d2c into main 2026-10-04 01:17:32 -04:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: logan/server-26#194