Protect and atomically consume first administrator bootstrap #242

Closed
opened 2026-11-01 07:16:10 +00:00 by kilo · 5 comments
Member

Problem

Foundry's secure first-run installation needs an independently authorized, single-use initial administrator claim. At canonical develop revision 209f7d39f3ecebbd1b98b11d7c44c63192fe50a4, both the JSON bootstrap endpoint and browser onboarding share service_bootstrap_admin() without a separate claimant authority. TLS and loopback publication do not by themselves establish who is authorized to claim a reachable fresh server.

Source inspection also identifies a potential first-claim race: scarcity_router/control_api.py:1254-1273 checks admin_configured() before password hashing and the store write; scarcity_router/server_store.py:1223-1255 uses INSERT ... ON CONFLICT DO UPDATE and deletes existing admin sessions. The gateway uses ThreadingHTTPServer. Two overlapping requests can therefore potentially both pass the check and a later write replace the earlier identity. Existing sequential bootstrap tests do not establish atomic single-winner behavior. This is source-level evidence; a runtime exploit or browser CSRF has not been demonstrated.

The browser /admin/onboarding form and JSON /control/bootstrap/admin both require assessment; a direct forged Origin header on its own does not establish browser CSRF. Foundry should not implement a second administrator gate in place of an SR-owned contract.

Acceptance

  • Define an independently provisioned and authenticated first-claim authority, threat model, expiry and secure delivery; protect both UI and JSON paths and avoid logging or exposing claim credentials in unauthenticated endpoints.
  • Atomically consume authority and create the initial administrator identity with insert-only first-writer semantics; no losing attempt may replace the winning identity, revoke its session, or receive a valid session.
  • Include deterministic concurrent tests, replay/unauthorized attempts, browser-origin protections appropriate to the threat model, and direct client coverage for both routes.
  • Specify and test behavior across restart, interruption and recovery, including legitimate operator recovery without introducing a reusable or unauthenticated reset path.
  • Preserve standalone SR operation and verified TLS contracts. Coordinate Foundry dependency: Creatidy/foundry#5.
## Problem Foundry's secure first-run installation needs an independently authorized, single-use initial administrator claim. At canonical `develop` revision `209f7d39f3ecebbd1b98b11d7c44c63192fe50a4`, both the JSON bootstrap endpoint and browser onboarding share `service_bootstrap_admin()` without a separate claimant authority. TLS and loopback publication do not by themselves establish who is authorized to claim a reachable fresh server. Source inspection also identifies a potential first-claim race: `scarcity_router/control_api.py:1254-1273` checks `admin_configured()` before password hashing and the store write; `scarcity_router/server_store.py:1223-1255` uses `INSERT ... ON CONFLICT DO UPDATE` and deletes existing admin sessions. The gateway uses `ThreadingHTTPServer`. Two overlapping requests can therefore potentially both pass the check and a later write replace the earlier identity. Existing sequential bootstrap tests do not establish atomic single-winner behavior. **This is source-level evidence; a runtime exploit or browser CSRF has not been demonstrated.** The browser `/admin/onboarding` form and JSON `/control/bootstrap/admin` both require assessment; a direct forged Origin header on its own does not establish browser CSRF. Foundry should not implement a second administrator gate in place of an SR-owned contract. ## Acceptance - Define an independently provisioned and authenticated first-claim authority, threat model, expiry and secure delivery; protect both UI and JSON paths and avoid logging or exposing claim credentials in unauthenticated endpoints. - Atomically consume authority and create the initial administrator identity with insert-only first-writer semantics; no losing attempt may replace the winning identity, revoke its session, or receive a valid session. - Include deterministic concurrent tests, replay/unauthorized attempts, browser-origin protections appropriate to the threat model, and direct client coverage for both routes. - Specify and test behavior across restart, interruption and recovery, including legitimate operator recovery without introducing a reusable or unauthenticated reset path. - Preserve standalone SR operation and verified TLS contracts. Coordinate Foundry dependency: https://forgejo.creatidy.com/Creatidy/foundry/issues/5.
Author
Member

Current owner triage, 2026-11-01: P1, immediate security. First actionable target, not implementation authorization in this triage. At develop 0493ed2b1892be6df0f96fb227fc96c68186e229, source indicates a potential first-claim check/write race, not an observed exploit. Router owns independently authenticated initial authority and atomic single-winner consumption for both bootstrap routes; earliest work is deterministic concurrent reproduction and bounded threat/claim/recovery design. Full implementation and independent security acceptance remain required; preserve standalone and TLS boundaries. Foundry's downstream integration does not replace Router authority.

**Current owner triage, 2026-11-01: P1, immediate security.** First actionable target, not implementation authorization in this triage. At develop `0493ed2b1892be6df0f96fb227fc96c68186e229`, source indicates a potential first-claim check/write race, not an observed exploit. Router owns independently authenticated initial authority and atomic single-winner consumption for both bootstrap routes; earliest work is deterministic concurrent reproduction and bounded threat/claim/recovery design. Full implementation and independent security acceptance remain required; preserve standalone and TLS boundaries. Foundry's downstream integration does not replace Router authority.
Author
Member

Implementation PR #243 is open at 2bdb6459d1841555f8aceda422a0e53400fa0705 over 0493ed2b1892be6df0f96fb227fc96c68186e229. The barrier-controlled pre-fix service test reproduced two accepted concurrent first claims; no real-world exploit is claimed. Local full gate 3203 tests passed/18 skipped, basedpyright and package-check passed, including installed composed-server claim issuance and bootstrap. Independent security/correctness/UX review and current Forgejo CI remain pending; no merge or release.

Implementation PR #243 is open at `2bdb6459d1841555f8aceda422a0e53400fa0705` over `0493ed2b1892be6df0f96fb227fc96c68186e229`. The barrier-controlled pre-fix service test reproduced two accepted concurrent first claims; no real-world exploit is claimed. Local full gate 3203 tests passed/18 skipped, basedpyright and package-check passed, including installed composed-server claim issuance and bootstrap. Independent security/correctness/UX review and current Forgejo CI remain pending; no merge or release.
Author
Member

PR #243 is READY_TO_MERGE at 17908f41111039aa0deaf4c3b9026fdb68923069 over 0493ed2b1892be6df0f96fb227fc96c68186e229: full local tests/typing/package checks pass, independent review #2 APPROVE with empty findings, and exact-HEAD Forgejo workflow #3431 succeeded. Standalone issue delivery does not authorize merge or issue closure, so both remain open; no deployment or release.

PR #243 is READY_TO_MERGE at `17908f41111039aa0deaf4c3b9026fdb68923069` over `0493ed2b1892be6df0f96fb227fc96c68186e229`: full local tests/typing/package checks pass, independent review #2 APPROVE with empty findings, and exact-HEAD Forgejo workflow #3431 succeeded. Standalone issue delivery does not authorize merge or issue closure, so both remain open; no deployment or release.
Author
Member

Bounded owner-authorized /loop selects #242 only: the fresh canonical open-issue queue places this sole P1 issue ahead of P2/P3, with no native dependencies or exclusion labels. Continue existing PR #243, preserving review #1 REQUEST_CHANGES and #2 APPROVE at HEAD 17908f41111039aa0deaf4c3b9026fdb68923069 / base 0493ed2b1892be6df0f96fb227fc96c68186e229; exact-HEAD workflow #3431 succeeded. Scope ends after verified integration and closure; no other issue is selected.

Bounded owner-authorized `/loop` selects #242 only: the fresh canonical open-issue queue places this sole P1 issue ahead of P2/P3, with no native dependencies or exclusion labels. Continue existing PR #243, preserving review #1 REQUEST_CHANGES and #2 APPROVE at HEAD `17908f41111039aa0deaf4c3b9026fdb68923069` / base `0493ed2b1892be6df0f96fb227fc96c68186e229`; exact-HEAD workflow #3431 succeeded. Scope ends after verified integration and closure; no other issue is selected.
Author
Member

Completed under the bounded owner-authorized /loop: PR #243 merged into develop as a1c9e78c335e1b6286e17c1455a3665fc83889ee. Verified merge parents are approved base 0493ed2b1892be6df0f96fb227fc96c68186e229 and approved HEAD 17908f41111039aa0deaf4c3b9026fdb68923069; integrated tree 96234c19e4032d11ecef464d032b980f80672f41 exactly matches approved HEAD. Issue acceptance is supported by atomic single-use claim implementation, both onboarding paths and recovery/negative/installed tests; review #1 requested UX changes and review #2 independently approved with empty findings; local make check 3204 tests/18 skipped, basedpyright and package-check passed, exact-HEAD Forgejo workflow #3431 succeeded. No live provider inference, release or deployment claimed.

Completed under the bounded owner-authorized `/loop`: PR #243 merged into `develop` as `a1c9e78c335e1b6286e17c1455a3665fc83889ee`. Verified merge parents are approved base `0493ed2b1892be6df0f96fb227fc96c68186e229` and approved HEAD `17908f41111039aa0deaf4c3b9026fdb68923069`; integrated tree `96234c19e4032d11ecef464d032b980f80672f41` exactly matches approved HEAD. Issue acceptance is supported by atomic single-use claim implementation, both onboarding paths and recovery/negative/installed tests; review #1 requested UX changes and review #2 independently approved with empty findings; local `make check` 3204 tests/18 skipped, basedpyright and package-check passed, exact-HEAD Forgejo workflow #3431 succeeded. No live provider inference, release or deployment claimed.
kilo closed this issue 2026-11-01 15:59:35 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Creatidy/scarcity-router#242
No description provided.