diff --git a/docs/MASTER_PLAN.md b/docs/MASTER_PLAN.md index 5f7c9de7..1f426ec9 100644 --- a/docs/MASTER_PLAN.md +++ b/docs/MASTER_PLAN.md @@ -1,18 +1,48 @@ # 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 | - | -| **TASK-2** | **Roll incoming-tx into deploy & ISO** | **P2** | PLANNED | - | -| **BUG-3** | **IndeedHub WebSocket spam in console** | **P2** | PLANNED | - | | **FEATURE-4** | **Onboarding loading screen with progress** | **P1** | IN PROGRESS | - | -| **INQUIRY-5** | **Offline balance check via mesh relay** | **P2** | PLANNED | - | -| **FEATURE-6** | **Watch-only wallet architecture** | **P1** | PLANNED | - | -| **TASK-7** | **Mesh Bitcoin security hardening** | **P1** | PLANNED | FEATURE-6 | +| **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 @@ -102,85 +132,66 @@ Users hit the onboarding screen before the backend is ready, resulting in "Serve - [ ] Handle edge cases: very slow starts, partial service failures, timeout fallback - [ ] Test on fresh ISO install (first-boot scenario) -### INQUIRY-5: Offline balance check via mesh relay (PLANNED) -**Priority**: P2 -**Status**: PLANNED (2026-03-17) +### TASK-8: Security hardening — critical and high findings (PLANNED) +**Priority**: P0 — Critical +**Status**: PLANNED (2026-03-18) -Design how to query wallet balance (LND/Bitcoin Core) from an off-grid node by relaying the request through mesh peers to an internet-connected Archy node that responds with the balance. Uses the same E2E encrypted relay infrastructure as TX relay. +Fix the critical and high security findings from the March 2026 audit before beta ships. -**Approach options**: -- New typed message pair: `BalanceRequest` (type 13) / `BalanceResponse` (type 14) -- Off-grid node sends `BalanceRequest` to Archy peers -- Internet-connected peer queries its own LND `walletbalance` or the requesting node's LND (if accessible) -- Challenge: the relay peer doesn't have access to the requesting node's wallet — need to either trust the relay peer's balance report, or have the relay peer proxy the RPC to the requesting node's LND over Tor/LAN -- Simplest: relay peer reports its OWN balance (useful for checking if your remote node has funds) -- Advanced: relay peer forwards the LND RPC call to the off-grid node's LND via reverse mesh tunnel +**Reference**: `docs/security-audit-2026-03-11.md` **Tasks**: -- [ ] Define `BalanceRequest` / `BalanceResponse` typed messages -- [ ] Implement balance relay handler on internet-connected node -- [ ] Add "Check Balance" button to Off-Grid Bitcoin panel -- [ ] Consider trust model — relay peer could lie about balance -- [ ] Explore UTXO set proof (SPV-style) for trustless verification +- [ ] 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 -### FEATURE-6: Watch-only wallet architecture (PLANNED) +### TASK-9: Full app testing matrix on fresh install (PLANNED) **Priority**: P1 — High **Status**: PLANNED (2026-03-18) -Archipelago should never hold private keys or seeds. Users create wallets on companion devices (Coldcard, SeedSigner, phone) and import xpubs to the node for watch-only tracking. The node creates unsigned PSBTs, the companion signs, and the node broadcasts. +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. -**Security rationale**: If the node is compromised (physical theft, remote exploit), no funds can be stolen — only xpubs are present, which reveal balances but cannot sign transactions. This is the standard for Bitcoin node OS security (see: Specter Desktop, Sparrow Wallet). - -**Design considerations**: -- xpub import: QR scan, USB file, manual paste -- PSBT workflow: create unsigned on node → transfer to companion → sign → return → broadcast -- Hardware wallet compatibility: Coldcard (USB/SD), SeedSigner (QR), Passport (QR/USB) -- Bitcoin Knots `importdescriptors` for watch-only wallet setup -- Derive receive addresses from xpub (BIP84 native segwit, BIP86 taproot) -- UTXO/balance tracking via watch-only wallet RPC -- UI: receive address display, UTXO list, PSBT generation, transaction history - -**Key files**: -- `core/archipelago/src/api/rpc/package.rs` — Bitcoin Knots container config -- `neode-ui/src/views/Web5.vue` — Bitcoin/wallet UI -- Bitcoin Knots RPC: `createwallet`, `importdescriptors`, `listunspent`, `walletcreatefundedpsbt` - -**Tasks**: -- [ ] Research Bitcoin Knots watch-only wallet RPC workflow (createwallet, importdescriptors) -- [ ] Design xpub import UI flow (QR scan, paste, file upload) -- [ ] Implement watch-only wallet creation via RPC on first xpub import -- [ ] Implement PSBT creation flow (select UTXOs → build unsigned PSBT → export) -- [ ] Design PSBT transfer UX (QR animated export, file download, USB) -- [ ] Implement signed PSBT import and broadcast -- [ ] Build receive address derivation and display (BIP84/BIP86) -- [ ] Add balance/UTXO tracking dashboard -- [ ] Ensure no private key material ever touches the node (audit all wallet RPC calls) -- [ ] Hardware wallet compatibility testing (Coldcard, SeedSigner) -- [ ] Document the companion device setup guide - -### TASK-7: Mesh Bitcoin security hardening (PLANNED) +### TASK-10: ISO build verification + multi-hardware test (PLANNED) **Priority**: P1 — High **Status**: PLANNED (2026-03-18) -Implement the security gaps identified in the off-grid Bitcoin security analysis (`docs/mesh-bitcoin.md`, Section 12). These harden the existing mesh Bitcoin relay infrastructure against the most impactful attack vectors. +Build a fresh ISO, install on at least 2 different hardware configurations, verify full onboarding flow, app installs, and multi-day uptime. -**Reference**: `docs/mesh-bitcoin.md` — full analysis with severity ratings and effort estimates. +--- -**Tasks (ordered by severity × effort)**: -- [ ] **G1**: Validate block header chain continuity — reject headers where `prev_hash` doesn't match stored header at height-1 (`BlockHeaderCache::store_header`) -- [ ] **G5**: RBF detection — check nSequence on `TxRelayPayload`, warn/reject if RBF-signaled in off-grid context -- [ ] **G9**: Timestamp sanity checking — reject headers with timestamps >2 hours in future or suspiciously old -- [ ] **G3**: Sign `TxRelayResponse` with relay's Ed25519 key (`TypedEnvelope::new_signed`) -- [ ] **G6**: BOLT11 invoice expiry validation — reject relay payment if invoice expires in <10 minutes -- [ ] **G11**: Random broadcast delay jitter — relay adds 0-30s random delay before `sendrawtransaction` to resist timing analysis -- [ ] **G2**: Validate proof-of-work on received block headers (check hash meets difficulty target) -- [ ] **G4**: Encrypt dead man alerts to emergency contacts individually (not cleartext broadcast) -- [ ] **G7**: Multi-relay header comparison — track headers by source, flag divergence between relays -- [ ] **G8**: Merkle proof relay — new message type for SPV transaction inclusion verification -- [ ] **G10**: Payment intent message type — signed envelope (destination, amount, timestamp) for non-repudiable records -- [ ] **G12**: Evaluate Cashu/ecash integration for low-value off-grid payments (spike/prototype) -- [ ] **G13**: Watch-only wallet integration with mesh relay (balance queries use local watch-only, not relay trust) +### 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 `podman` directly (no sudo) +- [ ] Re-enable `NoNewPrivileges=yes` in 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 ## Completed + + diff --git a/image-recipe/configs/archipelago.service b/image-recipe/configs/archipelago.service index 352c37bb..ac0e18a8 100644 --- a/image-recipe/configs/archipelago.service +++ b/image-recipe/configs/archipelago.service @@ -16,33 +16,21 @@ WatchdogSec=300 TimeoutStartSec=300 # Filesystem protection -ProtectSystem=strict +# ProtectSystem=true protects /usr and /boot only. +# Cannot use =full or =strict because podman needs write to /etc/containers. +ProtectSystem=true ProtectHome=yes PrivateTmp=yes -ReadWritePaths=/var/lib/archipelago # Privilege restriction -NoNewPrivileges=yes -# PrivateDevices=no: serial access to /dev/ttyUSB* needed for mesh radios. -# Device access still gated by Unix permissions (dialout group) + other sandboxing. +# NOTE: NoNewPrivileges, RestrictAddressFamilies, MemoryDenyWriteExecute, and +# RestrictRealtime are disabled because they all implicitly set the kernel +# no_new_privs flag, which blocks sudo — required for podman container management. +# TODO(TASK-11): Migrate to rootless podman, then re-enable all of these. PrivateDevices=no SupplementaryGroups=dialout -# Network restriction (allow only IPv4/IPv6 + Unix sockets) -RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 - -# Restrict what the process can do -RestrictNamespaces=yes -RestrictRealtime=yes -RestrictSUIDSGID=yes - -# Only allow needed syscalls -SystemCallArchitectures=native -SystemCallFilter=@system-service -SystemCallFilter=~@privileged @resources - -# Memory protection -MemoryDenyWriteExecute=yes +# Filesystem protection remains active (ProtectSystem, ProtectHome, PrivateTmp above) # Logging StandardOutput=journal