Scanning archi-dev-box from OUTSIDE found five ports serving their screens with no login — lnd-ui 18083, bitcoin-ui 8334, fips-ui 8336, electrs-ui 50002 and the Fedimint Guardian 8175 — none of which appeared in the gate's unprotected list. They are host-networked, so Podman publishes nothing to pin and their manifests declared 'ports: []'; the gate builds its map from declared ports, so it neither protected them nor reported them. An audit that reports success while five screens are open is worse than no audit. Their nginx now listens on 127.0.0.1 instead of 0.0.0.0, and each port is declared 'auth: gated' so the daemon owns the outside. 'bind:' on a host-networked app is a statement of where the container listens, not a publish instruction — quadlet already skips PublishPort in host mode. Guardian 8175 is declared on the fedimint app because its companion has no manifest, and the gate keys on port, not container. Credential paths were NOT exposed and are verified so: /lnd-connect-info, the /proxy/lnd/ passthrough, container logs and every RPC method through these screens all return 401 unauthenticated. What leaked was the page shell. Also fixes the delivery gap that would have made this unshippable: only bitcoin-ui, lnd-ui and electrs-ui were ever rsynced to /opt/archipelago/docker, so edits to fips-ui and fedimint-ui reached nodes through no path at all. All five now sync; the two whose rebuilds the daemon owns are synced without being handed to container-specs. Every remaining undeclared port is now declared with a stated reason — gated: botfights 9100, router 8084, pine 10380; exempt with rationale: fedimint consensus 8173/8174, gateway 8176/9737, netbird 8086/8087 (TLS + own auth, and enrolled devices cannot hold a session), pine TLS 10381, lightning-stack REST 8091 (macaroon, mirrors lnd). Zero undeclared ports remain across all 56 manifests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Archipelago
Self-sovereign Bitcoin node OS and manifest-driven app platform.
Archipelago is a bootable personal server OS for Bitcoin infrastructure,
self-hosted apps, mesh communication, decentralized identity, and federation.
Apps are packaged as declarative manifest.yml files and run as rootless
Podman containers managed by the Rust backend.
What is here
core/- Rust workspace: backend API, container runtime, security, OpenWrt helpers, and performance/resource management.neode-ui/- Vue 3 + TypeScript frontend.apps/- app manifests and custom app container sources.docker/- supporting container build contexts for UI companion surfaces.image-recipe/- bootable image/ISO build inputs.Android/- Android companion app.scripts/- development, release, deployment, and validation tooling.docs/- architecture, app packaging, operations, API, and roadmap docs.
Platform model
Archipelago is built as a developer-ready app platform, not a fixed appliance:
- Apps are declared in
apps/<app-id>/manifest.yml. - The Rust parser in
core/container/src/manifest.rsis the canonical schema. - The orchestrator compiles manifests to rootless Podman/Quadlet runtime state.
- App data lives under
/var/lib/archipelago/<app-id>/. - Secrets are generated or read from
/var/lib/archipelago/secrets/and injected through Podman secrets rather than static environment values. - Release and app catalogs are signed and verified against a pinned trust anchor.
Start with:
- Architecture
- Developer Guide
- App Developer Guide
- App Manifest Spec
- Nostr Git Source Hosting Plan
- Operations Runbook
- Troubleshooting
Quick start
Frontend
cd neode-ui
npm install
npm start
The dev UI runs at http://localhost:8100 with a mock backend on :5959.
Backend
cd core
cargo build
cargo test --all-features
Linux is the supported backend runtime and release-build target. macOS is fine for frontend work and many Rust compile/test loops, but host integration tests that touch Podman, systemd, networking, or image build paths require Linux.
App manifests
./scripts/validate-app-manifest.sh apps/filebrowser/manifest.yml
python3 scripts/generate-app-catalog.py
python3 scripts/check-app-catalog-drift.py --release --strict
scripts/generate-app-catalog.py requires Python with PyYAML installed.
Documentation map
| Doc | Purpose |
|---|---|
| Architecture | System layers, crates, data paths, security model |
| Developer Guide | Local setup, code workflow, testing |
| API Reference | JSON-RPC API overview |
| App Developer Guide | How to package and test apps |
| App Manifest Spec | Manifest schema and validation rules |
| Nostr Git Source Hosting Plan | ngit/NIP-34 contribution workflow and maintainer model |
| Apps README | Packaged app catalog overview |
| Image Recipe | Bootable image build flow |
| Operations Runbook | Production operations and recovery |
| Open Source Readiness | Public-release cleanup checklist |
| Roadmap | Shipped, in-progress, and planned work |
| Unified Task Tracker | Launch hardening task list |
| Archive | Historical plans, audits, and handoffs |
Contributing
Read CONTRIBUTING.md before opening a pull request. For security issues, follow SECURITY.md and do not open a public issue.
License
Archipelago is licensed under the MIT License. Third-party notices are listed in NOTICE and generated license inventories in component release artifacts.