Files
ngit-grasp/tests/common
DanConwayDev 502c74c975 feat(private-repos): attach GRASP-08 credentials to private outbound Git fetches
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.
2026-08-15 14:34:01 +00:00
..