Ringspace Protocol Overview
The Web of Trust
What would it take to establish a closed network of creators who afforded some guarantee of humanity and verified identity to both visitors and other members of the network? Uses need two guarantees about a site in order to “trust” it.
- Identity: “Are you who you claim to be?”
- Reputation: “Are you known to act in good faith?”
No single site can provide these guarantees for itself. An HTTPS certificate does not guarantee identity; it only tells the user that their traffic is encrypted and that the encryption keying material follows a known chain of trust. Neither of those is about identity as we care about it here. Our concern is whether a site is an upstanding member of a trusted community: the webring. To establish our own chain of trust, we might try relying on other members of the ring to verify identity in some way. But mutual webs of trust like that fail in predictable ways, like gaps in the web (one member doesn’t trust the others or intentionally excludes another node) or coordinated attacks on one node.
Certificate trust relies on root certificate authorities that browsers and other HTTP clients have agreed to trust, based largely on reputation. There’s a starting point.
I think a webring with a trust layer needs one too. We’ll call this the “ring server.” Its job is to poll members of the ring for a consensus about identity and reputation—more on reputation later.
The broad strokes look like this:

The ring server provides a “polling place” for members of the ring to contribute their vote on the identity and reputation of other members of the ring. The server compiles the responses and reports back the results to anyone asking—a user visiting the site in question. That user is provided with more than just a checkmark, but a full story about what the ring thinks about this site: whether the identity matches expectations, and whether they are in good standing.
Design Details
Keep in mind this is work in progress, a proof of concept, and many implementation details remain. Still, this can be a solid starting point.
Each member of the ring produces a Ed25519 keypair for signing data. The private key is of course kept private. The public key is shared to other members and the ring server. Each member publishes a manifest containing their site’s details, including name, URL, description, and public key. There’s more in there as well, but we’ll get to that. The common location for the manifest is at .well-known/webrings.json underneath the web root. This manifest is signed by the site’s private key. When a user asks to verify a site, the site provides its manifest, allowing the server to compare the provided public key and signature with what the server has on record. The result is returned to the user, along with the voting results from the ring for the given server.
How does the ring server get the public keys in the first place? An invite code in the form of a UUIDv4 is created on the ring server, tied to the URL of the invited member site. The joining member submits a join request to the ring server’s API with the invite code and site details, including their public key. The invite code serves as authentication for this request, and should be shared by some other secure means. Ringspace does not provide the totality of what a community requires for communication; it is assumed other channels are available.
Keep in mind: inefficiency is a design goal in this system. In fact, we happily answering “No” to that most insipid of technology questions: dOeS iT sCaLe??
A webring should be a small group. Otherwise you’re not really building a human community that trusts one another anyway.
So that’s identity sorted. What about reputation?
Reputation Tracking
For me, reputation concerns human-generated material on the site, but you could imagine reputation meaning something much different for a certain webring. It might include topicality, accessibility standards, or tone. Whatever the community decides is worth upholding. So while we’re asking sites to vote on identity, we might as well ask them to vote on reputation as well. To keep it simple, the vote will comprise a binary for good_standing and a categorical string for reason. By categorical, we mean there would be a limited set of values accepted for that field—whatever the ring administrators decide.
This is where things start to get really interesting. If the votes are in sites’ manifests, you could imagine that a site being voted down would want to know who’s accusing them of what. If the vote is in the manifest, the accuser is public. That’s a safety issue, as it makes anyone voting against a site a potential target for retaliation. If we’re building a better web, we can’t introduce obvious attack vectors like that.
In addition to the site’s data, each member site manifest contains voting data on other members of the ring. A vote consists of a Standing—Good, Bad, or Neutral—and a description of the vote.
Why just three voting options? Why not a 1-10 scale, or 1-100? Voting should be simple, and provide strong signals to users about the reputation of a given site. A 1-10 scale where everyone votes 7 is not a strong signal. The Neutral option is available for the noncomittal.
One important distinction between a site’s manifest and a ring server’s manifest is that the server advertises two keys: the signing key, and a x25519 public encryption key. While Ed25519 is great for signing, it is inappropriate for encryption. Luckily, the libsodium offers the sealed boxes scheme for encrypting the votes with the ring server’s public encryption key. This guarantees that votes are only readable by the ring server. While sealed boxes do not guarantee provenance as signatures do, the member uses their signing key for that purpose.
The presence of a vote is apparent in the manifest, as the encrypted votes are visibly keyed by the vote subject URL. And even when users request validation of a site, the returned data is anonymized such that a vote breakdown is provided, along with an unlabeled set of descriptions. This provides context without clear attribution, for the protection of ring members.
Does this require significant trust in the ring server? It does, but since at least the presence of a vote would be visible in each manifest, there is at least a publicly verifiable record that a vote for (or against) a site exists, even if its content is not readable by the public.
Just as with identity, the server responds with the result, including reasons for negative votes. This allows users to accept the risk of reading the site if they so choose. That said, well-maintained rings would eventually take action against sites in poor standing, by means of revoking their public key.
An important role of the ring server is to track vote history of each member. This is to identify patterns of abuse. While public histories are anonymized, the ring administrators have a full audit trail to correlate voting activity.
Distributed Information
While the ring server provides an essential coordination role, the majority of the information comprising the ring is kept in each member’s webrings.json file. These manifests all contain the following data:
- Site-specific data (URL, public key, last updated timestamp)
- Ring server data (URL, public key)
- Votes (per-URL, vote data encrypted with server’s public key)
- Manifest signature (algorithm, signature, timestamp, original information)
With this simple manifest and a coordination server, a closed network of sites can begin to establish trust. New sites can join the ring, provided there is some mechanism for existing sites to be informed about new additions (working on that). The server can provide updated member listings upon request, or via another mechanism like an RSS feed. The latter would be particularly useful in helping to automate the update of member manifests.
Site/Ring management
Handling all aspects of a ring, either as a ring member or administrator, can be daunting. That’s why the reference implementation provides a single binary that serves as site CLI tool, ring CLI tool, and even the API server itself! One ringspace application handles all aspects of ring community management.
Multiple Rings
Suppose a site wanted to join multiple rings. The structure of webrings.json allows, this. It would even be possible for a site to have a Good reputation in one ring, but a Bad rep in another.
Threat Model
No trust system is perfect, and what I’m proposing here has some tried-and-true attack vectors.
Server Attacks
The use of a central server exposes the ring to compromise if the ring server itself is compromised. If a malicious actor gains control of the server, vote histories could be manipulated, additional sites added to the ring, sites removed from the ring, etc. Defending this server is a top priority for a ring community. Denial-of-service attacks are also of concern, so strategies like replication, load balancing, and even deploying tools like Anubis or web application firewall in front of the server would be a best practice.
PKI Compromise
Should any private key in the ring—including the server’s—be leaked, the ring could be compromised. A single site’s private key disclosure would allow spoofing of the site and a malicious actor to potentially submit fraudulent votes. One way to defend against this is to require both the private key for the keypair and an API key for the ring server. Is this true multi-factor authentication? Kinda, since arguably the private key is something you have, and could even be stored on dedicated hardware. Better than a single factor, I’d say. I’m trying to keep complexity down here, but nothing precludes the addition of more complex authentication to this technology if desired.
Ring Splitting
This one is as much a feature as a threat vector. One or more sites could decide to take their public keys and go elsewhere, establishing a new ring and web of trust. Assuming everyone plays ball with webrings.json and doesn’t modify their own server to look at a separate file, pointing to a different server, even with the same key, would invalidate the manifest for the original server.
People are free to change their minds and make new rings. That part is not a threat, per se. If so many people in a ring leave that the ring loses quorum, then yes, that would have significant impact. But that needs to be a choice people can make. On the other hand, a site hosting multiple manifests is acting in bad faith.
Vote Fatigue
From a site owner perspective, one of the difficult parts of this scheme is aintaining votes on sites. For a 10-site ring, every owner would need to maintain 9 votes for perfect polling. We could use a “no vote == good standing” policy, but then it would become quickly evident that whoever does have a vote in their manifest is voting negatively. That defeats the purpose of encrypting the vote content. There’s a solution to this we’ll get to in the next section.
What stops someone from copying a legitimate webrings.json to a clone, modifying the content, but still claiming to be part of the trusted ring?
Well, nothing. The trick is where verification takes place. If we rely on the old webring “widgets” on the sites themselves, the potential for abuse is significant. Instead, the verification code must be in the browser itself. A browser extension reasonably guarantees that the hosted manifest is advertising the same URL/Origin as its current location. If not, the tool alerts about potential spoofing.
If an attacker attempts to change the contents of the manifest, the signature no longer verifies. If they spoof the keys to make the signature verify, the key they advertise no longer matches the server’s, resulting in a failed validation.
Conflicts
What happens when Site A includes Site B in its manifest, but Site C does not? This is sort of a feature, and would be fully public information, unlike votes. The validation result would indicate something like “Site C does not recognize Site B as a member of the ring.” Broadly speaking, it’s important that the validation result is not a binary. Rather, it is a bit more of a story that the user can use to decide whether a site is trustworthy.
The same is true for reputation. The intention is not to create a firewall, but to provide users with information.