FIPS Mesh Plugin (fips)
Nostr-native FIPS peer networking and UDP NAT traversal for collaborative team apps in AppWeaver.
Command: /fips
Overview
The fips plugin manages:
- A dedicated, plugin-generated FIPS node identity (
fips_pubkey, encrypted at rest indb.sqlitevia core'sencryptSecret), keeping coreBOT_KEYisolated. - Experimental UDP + Nostr NAT Traversal (
udp-nostr-transport.ts):- Inspired by the
jmcorgan/fipsNostr discovery and traversal specification; Rust interoperability is not yet verified:- Publishes replaceable kind
37195overlay adverts (udp:nat). - Exchanges NIP-59 / NIP-44 gift-wrapped kind
21059TraversalOfferandTraversalAnswerevents over explicitly persisted invitation relays. - Performs STUN reflexive discovery + local LAN/loopback candidate gathering and 24-byte
NPTC/NPTAUDP hole punching. - Hands the punched UDP socket directly to
@fips/corefor Noise IK (FMP link) and Noise XK (FSP end-to-end session) encryption.
- Publishes replaceable kind
- Inspired by the
- Optional FIPS WebSocket seed URLs (
wss://...orws://127.0.0.1:...) as an additional carrier; automatic fallback after a failed UDP dial is not implemented. - A Peer Roster (
fips_peers) binding each teammate's humanmaster_pubkeyto their instance's 33-byte compressedfips_pubkey. - Capability Contract (
peer-network:v1) for listing peers and sending channel-multiplexed envelopes, while delivering inbound messages to consumer apps implementingpeer-channel:v1.
All application sync, xitdb storage, and Git-style merge/review logic stay in consumer team apps (such as todo-teams).
Commands
/fipsor/fips status— Show local FIPS identity (fips_pubkey,nodeAddr), runtime state, and explicit signal relays./fips invite <wss://relay> [--recipient <master_hex>]— Review and master-sign an expiringfips2:invitation using the connected Web UI signer./fips add <fips2:...>— Verify an invitation and sign its acceptance, or review and confirm an acceptance. Unsigned/raw-key imports are rejected./fips list— List configured peers and their connection status (online,connecting,offline)./fips ping <id>— Punch a UDP path via Nostr signaling (if not already connected) and measure end-to-end encrypted FIPS round-trip latency./fips show <id>— Show full details for a configured peer./fips delete <id>— Remove a peer from the roster./fips seeds [wss://... | clear]— View or update optional FIPS WebSocket seed URLs.
Ping is initiated from one side; the paired remote instance answers automatically. Failures identify connection setup (30-second deadline), sending (10 seconds), or waiting for pong (20 seconds after send). They return an error without crashing the bot. See diagnostics and remaining limitations.
The backend logs correlated signaling attempt IDs, per-relay publication results,
receive/rejection reasons, STUN mapping outcomes, UDP punching, and peer state.
Punching retries all candidates within its bounded window after recognized
destination/network send errors, with detailed error codes, candidate scopes,
continue/abort decisions and final attempt summaries. See the
diagnostics inventory for error policy
and log limits; locally queued probes do not establish delivery.
Use DEBUG=1 on both instances for extra FMP/FSP handshake details. Offer/answer
publication failures are surfaced directly instead of silently becoming answer
timeouts. Candidate addresses and decrypted signal payloads are omitted from logs.
Documentation
- Signed invitation and acceptance flow
- Networking glossary
- Nostr event example, STUN flow, and diagnostics
- Plugin architecture
- FIPS concepts and implementation boundaries
- How signaling relays are chosen
- Implementation progress and remaining work
- Vendored
mmalmi/fips-tsprovenance - Future of AppWeaver architecture