Skip to content

Relay identity semi trust - #93

Merged
buffrr merged 6 commits into
mainfrom
relay-identity-semi-trust
Aug 17, 2026
Merged

Relay identity semi trust#93
buffrr merged 6 commits into
mainfrom
relay-identity-semi-trust

Conversation

@buffrr

@buffrr buffrr commented Aug 17, 2026

Copy link
Copy Markdown
Member

No description provided.

buffrr added 6 commits August 17, 2026 16:12
Add a persisted secp256k1 signing identity (data_dir/identity_key,
generate-if-missing on first boot). Sign the served anchor root over a
domain-tagged (trust_id, height) payload, hashed with
libveritas::hash_signable_message so every language binding verifies it
with the verify_spaces_message primitive it already ships. Cache the
signature and re-sign only when the pair changes.

Serve it as X-Anchor-Sig (with X-Anchor-Pubkey for discovery) on
/anchors so a client pinning the relay's key can verify the root
end-to-end even when TLS terminates at a proxy.

Also stamp X-Certrelay-Version (from CARGO_PKG_VERSION, i.e. whatever
release-plz bumped) on every response and add version + anchor_pubkey
to /stats.
Add a construction-configured semi-trusted pool: SemiTrustedRelay
{url, pubkey} (key mandatory — a semi-trusted relay is a pinned
(url, key) pair), Quorum {All, AtLeast(n), Majority}, and
SemiTrustConfig held on the Fabric struct.

refresh_semi_trusted() HEADs each relay's /anchors, verifies the
X-Anchor-Sig over (root, height) via libveritas::verify_spaces_message
against the pinned key, and pins the root meeting quorum as the
semi-trusted anchor. On a quorum miss it keeps the existing anchor
untouched and reports the vote breakdown via SemiTrustResult
{trust_id, height, total, verified, agreed, required, quorum_met}.

Also: with_semi_trusted() builder, set_semi_trusted_pool() /
semi_trusted_pool() runtime setter+getter, and an (empty-until-keyed)
SEED_SEMI_TRUSTED default pool.
Mirror the Rust semi-trust API in the JS clients: SemiTrustedRelay
{url, pubkey}, Quorum ("all" | "majority" | {atLeast}), SemiTrustConfig
(via FabricOptions.semiTrusted, default empty + majority), and
SemiTrustResult.

refreshSemiTrusted() HEADs each relay's /anchors, verifies the
X-Anchor-Sig over the domain-tagged (root, height) payload, and pins the
quorum-winning root as the semi-trusted anchor; on a miss it keeps the
existing anchor. Adds setSemiTrustedPool()/semiTrustedPool().

Verification goes through a new provider.verifySpacesMessage capability
(wasm + react-native adapters) so no WebCrypto/sha256 is needed on any
platform — the relay signs the same payload via
libveritas::hash_signable_message.
Mirror the Rust/JS resolve_with_certs in the remaining clients
Add a resolve-with-certs doc snippet to each language example (Rust, Go,
Python, JS, Kotlin, Swift): resolve a handle, print each parent space
(immediate-parent-first) and the exported .spacecert chain length. Wired
into each example's main so the snippet stays exercised.
@buffrr
buffrr merged commit 04b6ed2 into main Aug 17, 2026
3 checks passed
@buffrr
buffrr deleted the relay-identity-semi-trust branch August 17, 2026 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant