- fips::service::active_unit() picks whichever fips unit is running
(archipelago-fips.service vs upstream fips.service) so
handle_fips_restart and handle_fips_reconnect don't silently no-op
on hosts where the archipelago-managed unit was never created.
- peer_connectivity_summary(anchor_candidates) replaces the old
identity-cache check. anchor_connected is now true when at least
one authenticated peer's npub matches the public anchor OR any
entry in seed-anchors.json, which matches what the user actually
cares about ("am I in the mesh?") rather than what the card used
to claim ("is this one specific public anchor reachable?").
- FipsStatus::query takes data_dir now (so it can read seed-anchors)
rather than identity_dir. All call-sites updated.
- handle_fips_reconnect re-pushes seed anchors after restart so the
new daemon gets dialed without waiting for the 5-min apply loop.
- FipsNetworkCard label drops "(fips.v0l.io)" — misleading now that
multiple anchors may be configured.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two new fields on the /rpc fips.status payload:
- authenticated_peer_count: how many FIPS peers the daemon has an
authenticated session to right now. 0 means isolated / not on
the mesh; >0 means traffic to any known npub can DHT-route.
- anchor_connected: true when the public anchor (fips.v0l.io,
npub1zv58cn7…) is present in the daemon's identity cache. The
anchor bootstraps DHT routing for general-case deployments, so
this is the best single-value indicator the UI can show for
"will federation traffic over FIPS work between previously-
unknown peers?"
Implementation: fips::service::peer_connectivity_summary shells
out to `sudo -n fipsctl show peers` + `... show identity-cache`
(archipelago user already has NOPASSWD:ALL per the ISO sudoers
and live fleet nodes, confirmed). Failure returns (0, false) so
the UI degrades to "unknown" state without crashing.
Only queried when service_active — pre-onboarding / daemon-down
nodes skip the fipsctl call entirely.
UI side (FipsNetworkCard) consumes the full status JSON, so the
two new fields are available via existing prop plumbing; visual
treatment can come later.
Also fixes ISO build (commit 3e04456c wasn't sufficient): the
Dockerfile needs `cargo build --release --bins` — upstream FIPS
added a `fips-gateway` binary target, and plain `cargo build
--release` only builds the default bin list, which caused
`cargo deb --no-build` to fail hunting for the missing binary.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Nodes without a seed-derived FIPS key (legacy deploys, fresh pre-onboarding
installs) were reporting "Awaiting seed" in the dashboard even when the
upstream fips.service was running — status.npub was None unless
/data/identity/fips_key.pub existed.
- fips/service.rs: new read_upstream_npub() reads /etc/fips/fips.pub
(bech32 text or raw 32 bytes) from the debian package.
- fips/mod.rs: FipsStatus::current() prefers the seed-derived npub,
falls back to the upstream key. service_active is now TRUE if either
archipelago-fips.service OR upstream fips.service is active; adds
upstream_service_state to the status payload.
- fips/update.rs: resolve the upstream default branch from the GitHub
repo API (jmcorgan/fips is on `master`, not `main`) instead of
hardcoding — future repo rename just works.
- network/router.rs + api/rpc/router.rs: diagnostics gain wifi_ssid from
`nmcli -t device` so the Network card can show the connected SSID.
- UI: Home.vue adds a FIPS row to the Local Network card; Server.vue
mounts the new FipsNetworkCard and shows SSID + FIPS Mesh rows;
HomeNetworkCard.vue removed (superseded by the inline rows).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bakes the FIPS (Free Internetworking Peering System) mesh daemon into
the node stack, supervised by archipelago alongside Tor. Runs as a
system service, identity derives from the same BIP-39 master seed, and
user-triggered updates track upstream main.
Identity
seed.rs: new HKDF label archipelago/fips/secp256k1/v1 → dedicated
secp256k1 key, distinct from the Nostr-node key for crypto isolation
but still seed-recoverable
identity.rs: writes fips_key[.pub] to /data/identity on onboarding,
chmod 0600; fips_key_exists / load_fips_keys / fips_npub accessors
Transport
TransportKind::Fips=3 inserted between LAN and Tor (Tor bumps to 4)
→ router prefers FIPS over Tor for all peer traffic
PeerRecord gains fips_npub + last_fips fields (serde(default) for
backward-compat with older nodes)
transport/fips.rs: NodeTransport stub, reports unavailable until the
daemon is live so router falls through to Tor cleanly
Federation invites
FederatedNode and FederationInvite carry optional fips_npub
create_invite / accept_invite / peer-joined callback thread it end
to end; signature domain deliberately unchanged — FIPS Noise does
its own session auth, so the unsigned hint only affects path
selection
crate::fips
config.rs: renders /etc/fips/fips.yaml and sudo-installs key material
service.rs: systemctl status/activate/restart/mask wrappers
update.rs: GitHub API check against upstream main; apply stubbed
until per-commit .deb artefact source is decided
RPC + dashboard
fips.status / fips.check-update / fips.apply-update / fips.install /
fips.restart registered in dispatcher
HomeNetworkCard.vue shipped standalone (unmounted — place in Home.vue
when ready); shows state pill, version, FIPS npub, update button,
activate button when key is present but service is down
ISO + systemd
archipelago-fips.service: conditional on key presence, masked by
default — backend unmasks after onboarding writes the key
build-auto-installer-iso.sh: multi-stage Dockerfile builds the FIPS
.deb from jmcorgan/fips main (fail-loud), COPYs it into rootfs, apt
installs it so trixie resolves deps; unit copied + masked
Version bump: 1.3.5 → 1.4.0
Tests: 33 new/updated passing (seed, identity, transport, federation,
fips module, transport::fips).
Known gaps: fips.apply-update returns a clear stub error until
upstream publishes per-commit .deb artefacts; HomeNetworkCard is not
mounted in Home.vue by default.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>