installer-setup WS-C: close /api/install/* after first-run sentinel#1126
Merged
Conversation
…un sentinel ADR-0012 removed auth from /api/install/*, so on a LAN-bound box anyone reaching the port could re-run POST /apply, /apply-selections, or /complete indefinitely — rewriting slots, re-dispatching pulls, or re-flipping first_run long after setup finished. Once the first-run sentinel exists (written by #1101/#1124), these three provisioning endpoints now refuse with 409 install.closed instead of re-provisioning. GET /state stays readable, and day-2 tools on this router (/probe, PUT /slots/{name}/model, /curated-models, /services*) stay open since they're legitimate post-setup operations, not re-provisioning. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #1105.
ADR-0012 removed auth from
/api/install/*, leaving the surface fully open on the local network. Once the first-run sentinel exists (written byPOST /apply//apply-selections//completeper #1101/#1124), anyone reaching the port could still re-trigger a full install, rewrite slots, or re-dispatch pulls indefinitely.InstallClosed(409,install.closed) and a_require_install_open()guard insrc/hal0/api/routes/installer.py.POST /apply,POST /apply-selections,POST /complete— so each refuses fast (before any body parsing / hardware probing / provisioning) once.first_run_doneexists.GET /stateis untouched and keeps reportingfirst_run: falseregardless.POST /probe,PUT /slots/{name}/model(used byhal0 model swaplong after setup — seesrc/hal0/cli/slot_commands.py),GET /curated-models,GET /services,POST /services/{unit}/repair. These aren't re-provisioning and gating them would break normal post-setup operation.Checklist
/api/install/*mutating install endpoints return a closed status once the first-run sentinel is setGET /statestill works and reportsfirst_run: falsepost-close/complete(or a re-run of/apply//apply-selections) after setup is a safe 409 refusal, not a crash or silent no-opTest plan
uv run ruff format src tests— no changesuv run ruff check src tests— all checks passeduv run ruff format --check src tests— all formatteduv run pytest tests/api/test_installer_routes.py tests/api/test_install_apply.py tests/api/test_apply_selections.py -q— 31 passeduv run pytest tests/ -q --ignore=tests/e2e— 4641 passed, 14 known pre-existing failures + 1 pre-existing error (hermes venv/state-render/wrapper, comfyui phase4, proxmox host detection, container spec dispatch, config-url-proxy, models-preview, settings-store, openwebui prewire) — confirmed identical onorigin/mainbefore this change, unrelated toinstaller.py🤖 Generated with Claude Code