Files
ngit-grasp/tests
DanConwayDev 7dc786827f feat(private-repos): require GRASP-08 advertisement for derived membership
Derived private membership previously admitted the NIP-11 owner of any
relay referenced by an accepted announcement. A public relay's owner
gains nothing legitimate from private membership - their relay enforces
no confidentiality for the repositories it mirrors - so minting access
for them needlessly widens the trust domain.

Approach: parse the GRASP `supported_grasps` extension array from the
raw NIP-11 body (the SDK type does not carry it) into a new
`RelayLimitHints::grasp08` flag, thread it through the connect-attempt
outcome, and only insert into `relay_owners` when the relay advertises
"GRASP-08". Absent or malformed documents mean "not a private service".
Operator-configured NGIT_PRIVATE_MEMBERS are unaffected.

Correctness assumptions: `relay_owners` is the sole source of derived
members (`effective_private_members`), so gating insertion gates the
whole derivation; removing a stale entry on a non-advertising session
keeps a relay that stops advertising GRASP-08 from retaining minted
membership past its next reconnect.

Test infrastructure: MockRelay can now serve a caller-provided NIP-11
document, `push_to_relay` gained an Authorization-header variant for
pushes to private services, and TestRelay gained a persistent-LMDB
private constructor. The integration test restarts the relay after
promotion because the private NIP-42 gate also applies to the internal
self-subscription, so locally published announcements only reach the
sync manager through the startup database load; that pre-existing
limitation is out of scope here.

Validation: new unit tests for the supported_grasps parse; integration
test proves a GRASP-08-advertising relay's owner is admitted while an
otherwise identical non-advertising relay's owner stays restricted.
cargo test --lib grasp08_flag and --test private_mode
derived_membership_requires_grasp08_advertising_relay pass.
2026-08-15 13:43:22 +00:00
..
2026-08-12 14:43:38 +00:00