Web-of-trust infrastructure

Is this person connected to you? Ask. Get a proof.

People and agents vouch for whoever they trust, with their own device keys. Your app asks whether trust reaches someone, and a yes comes with a zero-knowledge proof.

Or write to hello@rebellion.systems

Reachability answer
A path of trust from you to Mara Illustrative example. You connect to Mara through two people, drawn as dashed outlines because the proof does not reveal them. Other people in the graph are shown faintly. ? ? YOU MK Mara
scheme
ultrahonk-wot-path-v2
reachable
true
pathLength
3
policy
minTrust 50 · maxHops 3
in between
not revealed
check
Proof verified locally
@rebellion-systems/trust-graph-sdk
const policy = { scope: "identity" as const, minTrust: 50, maxHops: 3 };
const query = { sourceGraphKeyId: me, targetGraphKeyId: them, policy };
const authorization = await signer.signRead({ operation: "query-reachable", graphKeyId: myDevice, query });
const answer = await graph.queryReachability({ ...query, authorization });
const result = await createZkVerifier().verifyAttestation({ attestation: answer.attestation,
  verificationKey: wotPathVerificationKey(), jwks: pinnedJwks,
  question: { sourceGraphKeyId: me, targetGraphKeyId: them, ...policy } });
if (!result.verified) throw new Error(`Answer rejected: ${result.code}`);
const { reachable, pathLength } = result.verdict;  // read the verdict only after the gate
const policy = {
  scope: "identity" as const,
  minTrust: 50, maxHops: 3 };
const query = {
  sourceGraphKeyId: me,
  targetGraphKeyId: them, policy };
const authorization =
  await signer.signRead({
    operation: "query-reachable",
    graphKeyId: myDevice, query });
const answer = await graph
  .queryReachability({
    ...query, authorization });
const result = await createZkVerifier()
  .verifyAttestation({
    attestation: answer.attestation,
    verificationKey:
      wotPathVerificationKey(),
    jwks: pinnedJwks,
    question: {
      sourceGraphKeyId: me,
      targetGraphKeyId: them,
      ...policy } });
if (!result.verified)
  throw new Error(result.code);
const { reachable, pathLength } =
  result.verdict;
{ "attestation": {  // signed: read the verdict from here
    "scheme": "ultrahonk-wot-path-v2",
    "publicInputs": { "reachable": true, "pathLength": 3, "minTrust": 50, "maxHops": 3,
                      "graphEpochRoot": "…", … },
    "zkProof": "…", "verificationKeyHash": "6ef19d67…", "proof": "…",
    "assertion": { …, "establishes": [ … ], "doesNotEstablish": [ … ] } },  "reachable": true, "pathLength": 3, … }  // unsigned conveniences
{ "attestation": {
    "scheme":
      "ultrahonk-wot-path-v2",
    "publicInputs": {
      "reachable": true,
      "pathLength": 3,
      "minTrust": 50,
      "maxHops": 3,
      "graphEpochRoot": "…", … },
    "zkProof": "…",
    "verificationKeyHash":
      "6ef19d67…",
    "proof": "…",
    "assertion": { … } },  "reachable": true,
  "pathLength": 3, … }
01 What you can build

One question. Many places to ask it.

Anywhere your user meets a sender, a signer or an agent, your app can ask whether their trust reaches them.

  • Ships a server route exists
  • Build today from shipped parts
  • Concept, help wanted pieces missing
  1. 1Your user binds once
  2. 2The sender signs
  3. 3Your app asks from your user’s seat and verifies locally
02 How it works

Bind. Vouch. Ask and verify.

A device joins a persona once. People vouch from their own devices. Your app asks from your user’s node and checks the answer itself.

  1. 1 · bind

    A device joins a persona

    Each device makes its own key and binds it through an AuthenSee sign-in. Finalizing needs two one-time proofs.

  2. 2 · vouch

    Trust is one-way and signed

    Score someone from 0 to 100. The device that vouches signs it, and only its source can change it.

  3. 3 · ask & verify

    Policy in, proof out

    Ask from your own node with a minimum score and up to three hops. Check the proof locally against keys you pin.

Reachable · proof

A path exists. Nobody in between is revealed.

A verifier learns that a qualifying path exists in the cited graph epoch, and nothing about who is on it. If proving fails, the request fails: there is no signature-only positive.

Not reachable · signed report

No path found, and it says so plainly.

A negative answer is signed by the server and carries no proof, stated in machine-readable form. A circuit can show that a path exists; it can’t show that none does.

See the full query and verify
Query and verify@rebellion-systems/trust-graph-sdk
const query = {
  sourceGraphKeyId: myGraphNodeId,
  targetGraphKeyId: otherGraphNodeId,
  policy: { scope: "identity" as const, minTrust: 50, maxHops: 3 },
};
const authorization = await signBrowserGraphRead(key.privateKey, {
  operation: "query-reachable", graphKeyId: myGraphKeyId, query,
});
const response = await graph.queryReachability({ ...query, authorization });

const { createZkVerifier, wotPathVerificationKey } =
  await import("@rebellion-systems/trust-graph-sdk/zk");
const result = await createZkVerifier().verifyAttestation({
  verificationKey: wotPathVerificationKey(),
  attestation: response.attestation,
  jwks: pinnedAttestationJwks,      // pinned by your app, never fetched
  question: { sourceGraphKeyId: query.sourceGraphKeyId,
              targetGraphKeyId: query.targetGraphKeyId, ...query.policy },
});
if (!result.verified) throw new Error(`Answer rejected: ${result.code}`);
console.log(result.verdict);  // { reachable, pathLength }, signed and checked
03 Built on TrustGraph

The first client. Yours next.

Omnibus

Early access

“The network for humans who want to trust each other.”

Meet people your friends already trust. Omnibus is one app built on TrustGraph: it uses TrustGraph’s vouches and the trust paths between people.

Omnibus app screen: “2 of your people vouch for Miguel”, with the path You → Ana → Miguel.

Your app

A mail plugin, a message filter, a call tool, an agent. Tell us what you’re building.

Request access
04 Guarantees

Fails closed. Forgets on schedule.

  • Device-signed changes and queries
  • No signature-only positives
  • Verifiable history
  • Logs that can’t authorize
  • Metrics that can’t enumerate
  • 30-day log maximum

More in the docs: account deletion · the full API

05 Get started

Three steps. To a verified answer.

  1. 01

    Request early access

    The SDK is in early access, and a public package is coming soon. Email us, and we’ll add your app’s origin to the server allowlist by hand so the sign-in ceremony can return to your app.

    hello@rebellion.systems
  2. 02

    Build on staging

    Develop and test against staging with your early-access setup.

    Stagingtrust-staging.rebellion.systems
  3. 03

    Go to production

    Ship against production, pinning production’s own attestation key. It is separate from staging’s.

    Productiontrust.rebellion.systems

Build on the graph. Talk to us.

Or write to hello@rebellion.systems