docs(01-16): hold FED-07's on-node checkpoint, correct its requirement status
FED-07 was marked Complete when 01-11 landed, which was premature: the requirement text explicitly includes "existing installs with the default password get a migration path", and that migration has never been exercised on a node. Corrected to code-complete/verification-pending. Checkpoint step 1 was run read-only on archi-dev-box: the node is CLEAN (hash present, 600, service-owned, not the shipped default) and has NO gateway container — the app is installed but nothing runs and its data dir is empty. So rotation cannot fire naturally here, and the steps that matter most (data survives the recreate, new credential authenticates, old one rejected) have nothing to exercise without installing and seeding first. Deferred deliberately rather than run unattended: 30 containers are up with 4-8 days uptime (IndeeHub, Immich, BTCPay, netbird, strfry, …), the archipelago system service is active, and restarting it SIGKILLs containers until Quadlet is the default. The todo carries the full context plus two adjacent findings: fedimint-gateway is missing from handle_package_credentials (so a rotated password has no UI retrieval path), and photoprism ships a fixed admin password in its manifest. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
9e2d2ef236
commit
095664a8a7
@@ -20,7 +20,7 @@ declared exit criteria (multinode pass + workstreams B/C/F), `.planning/codebase
|
||||
- [x] **FED-06**: On-brand payment success animation — the invoice "paid" tick's circle uses the screensaver-style ring with outer EQ-segment lines (reuse `ScreensaverRing.vue`'s compact size) in place of the current success burst, applied consistently everywhere the paid tick shows
|
||||
- [ ] **FED-08**: Lightning invoices created by the wallet embed route hints (LND `private` flag) so nodes whose channels are unannounced can actually receive payments — diagnosed on archy-x250-mad2 2026-07-31, where every wallet-UI invoice had `route_hints: []` and was unroutable; the bug is unconditional and affects any node without a public channel
|
||||
- [ ] **FED-09**: The container doctor does not restart Tor on every run — it recognises Tor's own setgid `2700` hidden-service directory mode as correct rather than "fixing" it to `700` and restarting, a loop that reset Tor every ~5 minutes, starved it of its consensus/HSDir cache (`No more HSDir available to query`), and broke the mesh's Tor fallback entirely; genuinely permissive modes are still corrected, and a restart backoff makes the failure class non-recurring
|
||||
- [x] **FED-07**: Fedimint gateway never installs with a pre-set password — gateway credentials are generated per-install via manifest-declared `generated_secrets` (or explicitly set by the user), never baked into the image/manifest; existing installs with the default password get a migration path (BLOCKER — default credentials are a security hole)
|
||||
- [ ] **FED-07**: Fedimint gateway never installs with a pre-set password — gateway credentials are generated per-install via manifest-declared `generated_secrets` (or explicitly set by the user), never baked into the image/manifest; existing installs with the default password get a migration path (BLOCKER — default credentials are a security hole)
|
||||
|
||||
### UI Fixes (UIFIX) — user-reported blockers, added 2026-07-30
|
||||
|
||||
@@ -112,7 +112,7 @@ Which phases cover which requirements. Updated during roadmap creation.
|
||||
| FED-04 | Phase 1 | Complete |
|
||||
| FED-05 | Phase 1 | Pending |
|
||||
| FED-06 | Phase 1 | Complete |
|
||||
| FED-07 | Phase 1 | Complete |
|
||||
| FED-07 | Phase 1 | Code complete, on-node verification pending (01-16 Task 2) |
|
||||
| FED-08 | Phase 1 | Pending |
|
||||
| FED-09 | Phase 1 | Pending |
|
||||
| UIFIX-01 | Phase 1 | Pending |
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
---
|
||||
created: 2026-08-01T09:45:00.000Z
|
||||
title: Verify FED-07 gateway credential rotation on a real node (01-16 Task 2)
|
||||
area: security
|
||||
severity: major
|
||||
files:
|
||||
- core/archipelago/src/container/secrets.rs
|
||||
- core/archipelago/src/container/prod_orchestrator.rs
|
||||
- .planning/phases/01-federation-mesh-hardening/01-16-PLAN.md
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
FED-07's code is complete and pushed (`42652547` removed every shipped credential,
|
||||
`9e2d2ef2` added detection + rotation for nodes already carrying one), but **plan 01-16's
|
||||
blocking Task 2 checkpoint has never been run**, so the requirement is not closed. Two
|
||||
things are unproven:
|
||||
|
||||
1. **That the recreate actually preserves the gateway's data.** Rotation deliberately
|
||||
avoids any teardown: it changes the credential, which changes `secret_env_hash`, which
|
||||
the drift check reads as a container-label mismatch, which fires the platform's own
|
||||
recreate around the unchanged data directory, ports, volumes and container name. That
|
||||
chain is confirmed by reading the code (`prod_orchestrator.rs:3309` computes the hash,
|
||||
`:3374` compares the label) but has **never been observed running**.
|
||||
2. **That the rotated credential actually authenticates** and the old shipped one is
|
||||
rejected.
|
||||
|
||||
## Why it was deferred (2026-08-01)
|
||||
|
||||
Checkpoint step 1 was run read-only on archi-dev-box. Findings:
|
||||
|
||||
- **The node is CLEAN** — the hash file is present, `600`, `archipelago:archipelago`, and
|
||||
is *not* the shipped default. The legacy `fedimint-gateway-password` file also exists.
|
||||
- **There is no `fedimint-gateway` container.** The app is installed at
|
||||
`/opt/archipelago/apps/fedimint-gateway`, but nothing is running and
|
||||
`/var/lib/archipelago/fedimint-gateway` is empty. `archy-fedimint-ui` and
|
||||
`fedimint-clientd` are running, but they are not the gateway.
|
||||
|
||||
So the rotation path cannot fire naturally here, and steps 5–6 (data survived, gateway
|
||||
authenticates) have nothing to exercise. Proving it on this box means installing and
|
||||
starting the gateway first, then deliberately seeding the old value — which the plan's
|
||||
Planner Assumption already anticipates and requires be recorded.
|
||||
|
||||
The deploy itself is the blocker: **30 containers are running with 4–8 days uptime**
|
||||
(IndeeHub relay/minio/postgres/ffmpeg, Immich, BTCPay + nbxplorer, netbird, portainer,
|
||||
strfry, searxng, the archy UI set), the `archipelago` system service is active, and
|
||||
CLAUDE.md's standing rule is that restarting it SIGKILLs containers until Quadlet is the
|
||||
default. Step 8 then wants `tests/lifecycle/run-gate.sh` on the same box, which cycles
|
||||
install/stop/start/reinstall/reboot-survive. Dorian chose to hold rather than take that
|
||||
blast radius unattended.
|
||||
|
||||
## Solution
|
||||
|
||||
Run 01-16 Task 2's eight steps in a window where restarting `archipelago` on the target is
|
||||
acceptable. Two viable routes:
|
||||
|
||||
- **On archi-dev-box:** install + start `fedimint-gateway`, put some state in its data
|
||||
directory, seed the old hash into
|
||||
`/var/lib/archipelago/secrets/fedimint-gateway-hash`, deploy this build, restart, then
|
||||
run steps 3–8. Record that the affected state was seeded deliberately.
|
||||
- **On a node that runs the gateway for real** (.228 is the heavy 14-app node): the
|
||||
rotation path may exist naturally there, which is stronger evidence than seeding.
|
||||
|
||||
Either way, record in `01-16-SUMMARY.md`: the affected-or-clean verdict, the exact deploy
|
||||
command, whether the `secret_env_hash` recreate was observed firing, the gate result, and
|
||||
the fact that archy-x250-dev was offline (single-node verification with the second-node
|
||||
gap recorded honestly is the expected pattern).
|
||||
|
||||
## Related, found while doing 01-16
|
||||
|
||||
- **Operator recovery gap:** `handle_package_credentials`
|
||||
(`core/archipelago/src/api/rpc/package/install.rs:2093`) is a hardcoded if-chain covering
|
||||
only `filebrowser` and `photoprism`. `fedimint-gateway` falls through to an empty list,
|
||||
so after a rotation the operator has no in-UI way to get the new password — only the
|
||||
`0600` file the log line names. Adding one arm closes it; the UI already renders whatever
|
||||
the RPC returns.
|
||||
- **`apps/photoprism/manifest.yml:35` ships `PHOTOPRISM_ADMIN_PASSWORD=archipelago`**, and
|
||||
that same literal is handed to the UI. Same defect class as FED-07 on a different app —
|
||||
wants its own requirement.
|
||||
</content>
|
||||
Reference in New Issue
Block a user