diff --git a/.planning/todos/pending/2026-07-30-migrate-source-references-to-https-domain.md b/.planning/todos/pending/2026-07-30-migrate-source-references-to-https-domain.md index 0098a0d3..78b42792 100644 --- a/.planning/todos/pending/2026-07-30-migrate-source-references-to-https-domain.md +++ b/.planning/todos/pending/2026-07-30-migrate-source-references-to-https-domain.md @@ -1,30 +1,51 @@ --- created: 2026-07-30T22:19:31.770Z -title: Migrate all source references to https://source.archipelago-foundation.org (stop exposing VPS2 IP) +title: Migrate all VPS2 references to https://source.archipelago-foundation.org (stop exposing IP; TLS everywhere) area: security severity: blocker files: + - apps/*/manifest.yml + - app-catalog/catalog.json + - neode-ui/public/catalog.json + - core/archipelago/src (update.rs, container/registry.rs, image_versions.rs, image_policy.rs, quadlet.rs, prod_orchestrator.rs, app_catalog.rs, companion.rs, api/rpc/package/*) + - core/container/src/podman_client.rs + - core/archipelago/src/fips/anchors.rs - scripts/self-update.sh - scripts/first-boot-containers.sh - scripts/create-release.sh - scripts/create-release-manifest.sh - scripts/image-versions.sh - scripts/generate-app-catalog.sh - - scripts/deploy-bitcoin-knots.sh - - scripts/validate-app-manifest.sh - - .gitea/workflows/demo-images.yml + - scripts/bootstrap-switchover.sh - release-manifest.json + - releases/manifest.json + - tests/lifecycle/remote-lifecycle.sh + - .gitea/workflows/demo-images.yml + - neode-ui/src/components/CompanionIntroOverlay.vue --- ## Problem -Dorian (2026-07-30, critical): the Gitea source host is referenced everywhere as raw `http://146.59.87.168:3000` — plain HTTP, VPS2's bare IP exposed in shipped artifacts (release-manifest.json, self-update.sh, first-boot scripts run on every node) and CI workflows. Should be `https://source.archipelago-foundation.org` so the IP isn't baked into anything and transport is TLS. +Dorian (2026-07-30, CRITICAL): every VPS2 service is referenced by raw IP `146.59.87.168` — plain HTTP for most — exposing the IP in shipped artifacts and requiring insecure-registry config on every node. Everything must move to `https://source.archipelago-foundation.org` "perfectly so all the stuff we use it for works". -State verified 2026-07-30: DNS already resolves (A → 146.59.87.168), openresty serves HTTPS with a valid cert, and Gitea works through it (`git ls-remote https://source.archipelago-foundation.org/lfg2025/archy.git` succeeds). The local `gitea-ai` remote was already switched to the HTTPS domain. Remaining work is the reference migration + verification. +**Verified inventory (2026-07-30):** ~196 references. +- `:3000` (Gitea — git/raw/releases AND the OCI container registry): **194 refs** — every app manifest's `image:` field, both catalogs (app-catalog/catalog.json + neode-ui/public/catalog.json, 23 each), compiled Rust core (self-update, registry allow-list, image policy/versions, quadlet gen, package RPCs, podman client), OTA manifests (release-manifest.json, releases/manifest.json), lifecycle tests, release/first-boot/self-update scripts, CI workflows, docs, UI marketplace data. +- `:2100` (companion APK package server): 1 ref (`CompanionIntroOverlay.vue`). +- `:8444` (FIPS trust anchor, raw TLS — `ARCHY_ANCHOR_ADDR` in `fips/anchors.rs`): 1 ref. + +**Domain coverage verified live (2026-07-30):** +- git clone/ls-remote over HTTPS: ✓ (works; `gitea-ai` remote already switched) +- Gitea raw + releases: ✓ (HTTP 200) +- Container registry `/v2/` through the domain: ✓ (proper 401 auth-challenge; TLS pulls will work and the insecure-registry hack becomes removable) +- `:2100` APK server: ✗ NOT behind the domain — needs an openresty route/subdomain on VPS2 (Dorian/VPS2-side) +- `:8444` FIPS anchor: ✗ raw TLS service, can't share 443 — at minimum switch the constant to a DNS name (e.g. anchor host + :8444); check whether anchors pin certs before touching (security-sensitive) ## Solution -- Replace `http://146.59.87.168:3000` with `https://source.archipelago-foundation.org` across the files listed (grep for `146.59.87.168` repo-wide; ~10 files incl. release/OTA/self-update/first-boot paths). -- CAREFUL: self-update.sh and release-manifest.json drive OTA on live nodes — a wrong URL bricks updates. Verify each rewritten URL responds (curl) before commit; test self-update flow on a dev node before fleet rollout; keep migration non-destructive per repo invariants. -- Check whether older deployed nodes need the IP kept as a fallback during transition (nodes updating FROM an old release still hit the IP URL — the new manifest must be reachable at the old URL too until the fleet has rolled past it). -- Also audit for the raw IP in docs/ and any node-side configs. +Execute as a dedicated quick task IMMEDIATELY AFTER phase 2's 02-08 (don't disturb the dev-pair perf measurements; requires core Rust rebuild + node verification per CLAUDE.md discipline): +1. Mechanical rewrite of all `:3000` refs → `https://source.archipelago-foundation.org` (registry image refs become `source.archipelago-foundation.org/lfg2025/:` — no port, implies 443/TLS). +2. **Image-ref transition safety:** running containers/quadlets store the OLD image name; migration must not orphan or re-pull-break existing apps (migrations never destroy data). Plan the transition: catalog+manifests flip, orchestrator treats old/new registry names as equivalent during adoption, or staged re-tag. +3. Rebuild core, run the lifecycle gate on a dev node (NOT the fleet), verify: self-update fetch, catalog fetch, image pull via domain, app install end-to-end. +4. Keep the IP endpoints alive on VPS2 during transition — nodes updating FROM old releases still hit IP URLs (fallback window until fleet rolls past). +5. `:2100` + `:8444`: needs Dorian's VPS2-side config (openresty route for packages; DNS/cert decision for the anchor). Blocked-on-user items, tracked here. +6. Remove insecure-registry config from node provisioning once pulls verify over TLS.