The security hardening (NoNewPrivileges, RestrictAddressFamilies, MemoryDenyWriteExecute, RestrictRealtime, ProtectSystem=strict) all blocked podman container management via sudo. These are temporarily disabled until TASK-11 (rootless podman migration) is complete. Remaining active protections: ProtectSystem=true (/usr, /boot), ProtectHome=yes, PrivateTmp=yes, PrivateDevices=no (mesh radio). Also adds TASK-11 to MASTER_PLAN.md for tracking the rootless podman migration that will allow re-enabling full security hardening. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
10 KiB
MASTER PLAN
Archipelago project task tracking and roadmap.
BETA FREEZE ACTIVE (2026-03-18) — No new features. Fix bugs, harden security, test everything. Pipeline: Feature Testing → User Testing → Beta Live Progress:
docs/BETA-PROGRESS.md| Acceptance:docs/BETA-RELEASE-CHECKLIST.md
Roadmap
Phase 1: Feature Testing (internal) — CURRENT
| ID | Title | Priority | Status | Dependencies |
|---|---|---|---|---|
| BUG-1 | Random logout / CSRF mismatch | P0 | PLANNED | - |
| FEATURE-4 | Onboarding loading screen with progress | P1 | IN PROGRESS | - |
| BUG-3 | IndeedHub WebSocket spam in console | P2 | PLANNED | - |
| TASK-8 | Security hardening (CRIT-01, CRIT-02, HIGHs) | P0 | PLANNED | - |
| TASK-9 | Full feature testing sweep | P1 | PLANNED | - |
| TASK-10 | ISO build verification + multi-hardware test | P1 | PLANNED | - |
| TASK-11 | Rootless podman + restore security hardening | P1 | PLANNED | - |
| TASK-12 | Beta telemetry — node reporting + monitoring panel | P1 | PLANNED | - |
Phase 2: User Testing (controlled, real hardware)
| ID | Title | Priority | Status | Dependencies |
|---|---|---|---|---|
| TASK-13 | Recruit 3-5 test users, distribute ISOs | P1 | NOT STARTED | Phase 1 complete |
| TASK-14 | Monitor telemetry, triage + fix user-reported issues | P1 | NOT STARTED | TASK-12, TASK-13 |
| TASK-15 | Rebuild ISO with fixes, re-verify | P1 | NOT STARTED | TASK-14 |
Phase 3: Beta Live (public)
| ID | Title | Priority | Status | Dependencies |
|---|---|---|---|---|
| TASK-16 | Final ISO build + release notes + distribution | P1 | NOT STARTED | Phase 2 complete |
Post-Beta (FROZEN — do not start)
| ID | Title | Priority | Status | Dependencies |
|---|---|---|---|---|
| TASK-2 | Roll incoming-tx into deploy & ISO | P2 | DEFERRED | - |
| INQUIRY-5 | Offline balance check via mesh relay | P2 | DEFERRED | - |
| FEATURE-6 | Watch-only wallet architecture | P1 | DEFERRED | - |
| TASK-7 | Mesh Bitcoin security hardening | P1 | DEFERRED | FEATURE-6 |
Active Work
BUG-1: Random logout / CSRF mismatch (PLANNED)
Priority: P0 — Critical Status: PLANNED (2026-03-15)
Sessions expire unexpectedly during normal use. Backend sessions now persist to disk (/var/lib/archipelago/sessions.json) but CSRF token mismatch (403) still causes logouts. Need to investigate CSRF token lifecycle and fix the mismatch between cookie and header values.
Root cause analysis so far:
- Sessions were purely in-memory — fixed with disk persistence
- CSRF validation compares cookie value vs
X-CSRF-Tokenheader — both present but don't match - Log:
403 CSRF mismatch — rejecting RPC call ... has_cookie=true has_header=true - Possible cause: cookie value rotated (e.g., new login in another tab) but frontend cached old value
Key files:
core/archipelago/src/session.rs— session store (now persisted)core/archipelago/src/api/rpc/mod.rs:273-307— CSRF validationneode-ui/src/api/rpc-client.ts:18-45— frontend CSRF extraction from cookie
Tasks:
- Investigate CSRF token rotation — when/why cookie and header diverge
- Add logging to CSRF validation to capture actual cookie vs header values
- Consider returning CSRF token in response body (not just cookie) for explicit client storage
- Test multi-tab scenario where one tab's login rotates the CSRF token
- Verify session persistence survives deploys (second deploy test)
TASK-2: Roll incoming-tx into deploy & ISO (PLANNED)
Priority: P2 — Medium Status: PLANNED (2026-03-16)
The incoming transactions feature (lnd.gettransactions RPC + wallet badge UI + auto-refresh) is working on .228. Roll changes into deploy-to-target.sh and build-auto-installer-iso.sh so fresh installs and deploys get it automatically. Do not break existing changes.
Key files changed:
core/archipelago/src/api/rpc/lnd.rs— newhandle_lnd_gettransactionsmethodcore/archipelago/src/api/rpc/mod.rs— registeredlnd.gettransactionsrouteneode-ui/src/views/Web5.vue— incoming tx badge, panel, auto-refresh pollingneode-ui/src/style.css— incoming-tx-badge, incoming-tx-row, incoming-tx-slide classes
Tasks:
- Verify changes are already captured by existing deploy (backend build + frontend build)
- Ensure ISO build captures the updated Rust binary and frontend dist
- Test that no existing deploy/build logic is broken
BUG-3: IndeedHub WebSocket spam in console (PLANNED)
Priority: P2 — Medium Status: PLANNED (2026-03-16)
ws://localhost:7777/ connection refused fills browser console endlessly when IndeedHub is loaded in iframe. IndeedHub's compiled frontend bundle hardcodes localhost for WebSocket connections. When loaded from a remote host, localhost resolves to the user's machine, not the server.
Root cause: IndeedHub's Next.js build bakes localhost:7777 into the WebSocket URL. The nginx WebSocket proxy at /app/indeedhub/ws/ exists but is unused because IndeedHub loads via direct port 7777, not through the proxy path.
Tasks:
- Rebuild IndeedHub with
NEXT_PUBLIC_WS_URLenv var pointing to relative URL or actual server address - Alternatively, configure IndeedHub to use relative WebSocket URLs (
/ws/instead ofws://localhost:7777/) - Test that WebSocket reconnection works after the fix
FEATURE-4: Onboarding loading screen with progress (IN PROGRESS)
Priority: P1 — High Status: IN PROGRESS (2026-03-17)
Users hit the onboarding screen before the backend is ready, resulting in "Server is still starting up" errors that block identity creation. The onboarding flow should not begin until the server is fully operational.
Solution: Show the existing screensaver as a loading/boot screen with server startup progress. Swap the inner logo for animated pixel art icons (smiley face, Bitcoin logo, etc.) that cycle while services come online. Show progress indicators for each backend service (identity store, container runtime, LND, etc.). Only transition to onboarding once /health returns ready.
Key considerations:
- Reuse the existing screensaver component as the boot screen
- Animated pixel art icons rotate in the center (smiley, BTC, lightning bolt, etc.)
- Progress bar or status checklist showing which services are ready
- Poll
/healthendpoint for service readiness - Smooth transition from boot screen → onboarding once all critical services are up
- First-boot vs normal boot: first boot shows onboarding after, normal boot goes to dashboard
Key files:
neode-ui/src/views/Onboarding.vue— current onboarding flowneode-ui/src/components/Screensaver.vue— existing screensaver to repurposecore/archipelago/src/api/rpc/mod.rs— health endpointcore/archipelago/src/server.rs— startup sequence and service initialization
Tasks:
- Investigate current health endpoint — what services does it check, what's missing
- Design boot screen component: screensaver background + animated pixel icons + progress
- Create pixel art icon set (smiley, BTC, lightning, shield, etc.) as SVG/CSS animations
- Implement service readiness polling (health check with granular service status)
- Add backend support for granular startup progress (which services are ready)
- Build boot screen component with smooth transition to onboarding/dashboard
- Handle edge cases: very slow starts, partial service failures, timeout fallback
- Test on fresh ISO install (first-boot scenario)
TASK-8: Security hardening — critical and high findings (PLANNED)
Priority: P0 — Critical Status: PLANNED (2026-03-18)
Fix the critical and high security findings from the March 2026 audit before beta ships.
Reference: docs/security-audit-2026-03-11.md
Tasks:
- CRIT-02: Replace hardcoded Bitcoin RPC password with per-install random generation
- CRIT-01: Redesign secrets encryption key derivation (Argon2 from user password or hardware-backed)
- HIGH-01: Add Content-Security-Policy headers to nginx
- HIGH-02: Enable HSTS in nginx
- HIGH-03: Fix rate limit IP spoofing (trust only known proxies for X-Forwarded-For)
- HIGH-04: Bind Bitcoin RPC to localhost only (not 0.0.0.0)
- HIGH-05: Remaining high finding from audit
TASK-9: Full app testing matrix on fresh install (PLANNED)
Priority: P1 — High Status: PLANNED (2026-03-18)
Run through the complete docs/BETA-RELEASE-CHECKLIST.md app matrix on a fresh ISO install. Every app: install, launch, UI loads, uninstall. Every dependency chain: correct errors when deps missing.
TASK-10: ISO build verification + multi-hardware test (PLANNED)
Priority: P1 — High Status: PLANNED (2026-03-18)
Build a fresh ISO, install on at least 2 different hardware configurations, verify full onboarding flow, app installs, and multi-day uptime.
TASK-11: Rootless podman + restore security hardening (PLANNED)
Priority: P1 — High Status: PLANNED (2026-03-18)
Migrate from sudo podman (root containers) to rootless podman so the systemd service can run with NoNewPrivileges=yes and SystemCallFilter restrictions. Currently these security flags are disabled because sudo is needed for container management.
Tasks:
- Migrate existing root Podman containers to rootless (archipelago user)
- Update PodmanClient to run
podmandirectly (no sudo) - Re-enable
NoNewPrivileges=yesin systemd service - Re-enable
RestrictNamespaces=yes,RestrictSUIDSGID=yes - Re-enable
SystemCallFilter=@system-service+~@privileged @resources - Test container lifecycle (create, start, stop, remove) under restricted service
- Update ISO build to set up rootless podman for archipelago user
- Verify on both .228 and .198
Post-Beta (FROZEN)
These tasks are deferred until after beta ships. Do not start.
- INQUIRY-5: Offline balance check via mesh relay
- FEATURE-6: Watch-only wallet architecture
- TASK-7: Mesh Bitcoin security hardening
- TASK-2: Roll incoming-tx into deploy & ISO