mirror of
https://relay.ngit.dev/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp.git
synced 2026-10-06 07:28:23 +00:00
A private instance mirroring another private service could open the authenticated WebSocket but had no way to fetch the git data behind the peer's NIP-98 gate, so purgatory promotion of mirrored repositories never completed. This is the missing half of zero-configuration private mirroring. Approach: a new Grasp08Peers registry (canonical host:port keys with explicit ports, since loopback tests co-host several services on one address) is populated by the sync manager whenever a session's NIP-11 advertises GRASP-08 and drained when it stops. The purgatory fetch path consults it per URL and, for confirmed peers, attaches the GRASP-08 repository-root credential via `http.extraHeader` on the hardened git command. Headers are minted fresh before each subprocess because the peer enforces a 60-second validity window that a long batch fetch must not outlive; signing failures warn once and degrade to unauthenticated fetches. Both the registry and the signing keys exist only when the server runs in private mode, so a public mirror can never present credentials. Correctness assumptions: `extract_domain` drops the port and is therefore unsuitable as the registry key; `peer_key` derives host:port from the URL itself on both the relay-URL (write) and clone-URL (read) sides. The `http.extraHeader` addition does not conflict with the `credential.helper=` hardening: that control excludes ambient operator credentials, while this header is a peer-scoped credential minted for exactly this vetted fetch target. Validation: unit tests cover the ws/http key equivalence and a credential round-trip through the inbound validator (including root derivation past `.git` inside identifiers). The integration test runs two private services end to end: the mirroring instance only serves the state event after NIP-42 on the WebSocket AND the NIP-98 credential on the git fetch both succeeded against the private source. cargo test --lib private:: and --test private_mode private_instance_syncs_from_private_peer_with_outbound_credentials pass.