Your own identity on the Internet

If you ever thought about having users login to your site, you’ve probably considered adding Facebook Login, or OAuth2 and OpenID Connect. And for good reason – they’re widely used.

An identity you own, to sign your content

But what if you wanted to allow users to own their identity? What would that look like? For a lot of technical folks, establishing identity usually means using a private key. Establishing identity using a private key also has the advantage that the user owns their own identity.

Let’s say that you establish your identity using your own private key. Any content you create can then be signed by you using your private key. Anyone can verify that it was you who created the content if they have your public key.

How does someone looking at a signed piece of content know what key was used to sign it? Well, you can publish your public key somewhere, and put a URL to that key next to the signature on the content you create. The URL would allow the reader to download the public key they need to verify the signature.


But what if the URL to the public key goes down? Well, we can setup mirrors for public keys (you might use alternatives such as key servers here). Users should be able to notify mirrors of a new public key that they’ve published. Sites hosting content can also send cached versions of public keys (that they picked up from the original source, or from a mirror) included in the content.

Claims, and verified claims

So far, we only have the ability to establish that some piece of content was created by someone owning a certain key. But we have not established who the person behind the key is as of yet. How can we do that? Well, let’s say that with every key, you can have a set of claims – metadata attributes associated with them. So for example, we can say some key key1 belongs to some user claiming that their fullName is Joe Blogs, and that their facebookProfile is (fullName and facebookProfile are claims here). Great, so now we can say that wherever we see content signed with key key1, it belongs to Joe Blogs, whose Facebook profile is at

Of course, the obvious problem with this is that anyone can publish their key, and associate it with a bogus set of claims. What we need is a way to have verified claims. For example, we would especially want to verify that someone who claims to own a particular Facebook profile actually owns that profile. How do we do that? Well we can have a service that provides verified facebookProfile claims. That is, a service that uses Facebook Login to allow the owner of a key to login to their Facebook account to prove ownership, and only then confirm that the owner of that key owns a Facebook account.

Here is how that flow might work:

  1. The owner of the key signs a facebookProfile claim with their private key – let’s call the signature they produce here claimSignature
  2. They provide claimSignature to the Facebook verification service, which should first check that the provided claimSignature is correct and was produced by the owner of the key
  3. It should then have them login to the Facebook profile they claim to own using Facebook Login
  4. Once the service has verified that they own the Facebook account, the service would then sign claimSignature, with it’s own private key to create a verifiedClaimSignature

Now, if we were given the claimSignature, and the verifiedClaimSignature, together with the facebookProfile claim, we can trust that association a bit more. We would need to decide to trust that the Facebook verification service we used is a trust-worthy service in evaluating facebookProfile claims. If we do, all we need is the public key for that service to verify the verifiedClaimSignature and confirm that the facebookProfile provided can be trusted.

Decentralized identity

What does this allow at the end of the day? Suppose you wrote a blog post, or posted a comment somewhere on the web. You can now sign that content, and someone reading the content would be able to know that it was you who wrote it. And they would be able to know that based on the identity you own – your personal private key. Everyone can own their own identity.

Weave social into the web

Disclaimer: This is the second post in a series where we are exploring a decentralized Facebook (here’s the first). It’s written by software engineers, and is mostly about imagining a contrived (for now) technical architecture.

How do you weave elements of Facebook into the web? Start by allowing them to identify themselves and all their content:

  • Establishing a user’s identity can be done rather straightforwardly by creating a unique public-private key pair for a user and allowing them to digitally sign things using their private key
  • Users can then digitally sign content they create anywhere on the internet – they can sign articles they publish, blog posts, comments, photos, likes and +1’s, anything really

Now that they’ve started to identify their content, it’s time to make everyone aware of it:

  • Notifications about content users generate needs to be broadcast in real-time to a stream of events about the user
  • Notifications can be published to the stream by the browser, or a browser plug-in, or by the third-party application on which the content was generated
  • Before being accepted into a user’s stream, notifications neet to be verified as being about the user and their content by the presence of a digital signature
  • Other parties interested in following a user can subscribe to a user’s feed

But that’s all in the public eye. To have a social network, you really need to allow for some privacy:

  • Encrypt data, and allow it to be decrypted selectively – this may include partial content – for example, it’d be useful to have a comment on an otherwise unencrypted site encrypted, only accessible by a select few consumers
  • Allow encrypted content to be sent over plain HTTP over TCP (not TLS) – this way the encrypted payload can be mirrored, and allow consumer privacy (if the consumer can access encrypted data from a mirror, it can do so privately, without the knowledge of the consumer)
  • Encryption is performed with a unique key for every piece of content
  • Decryption is selective in that the decryption key is given out selectively by the publisher (based on authorization checks they perform)

Deface, a decentralized Facebook

A disclaimer: we are a bunch of software engineers, so what follows is a wild technical thought experiment. Bring your imagination and your architectural chops.

What would a decentralized Facebook look like? Well, users should be able to:

  • Create a basic profile
  • Maintain one or more lists of friends
  • Share content with everyone on one or more of these lists
  • Have shared content only accessible by people on the list it was shared with
  • View content from all of their connections in one chronological “timeline”
  • View content from another user without the other user knowing how many times they’ve viewed it (consider how important it is that you can see someone’s photo on Facebook without them knowing, surreptitious as it sounds)

How would it work? Let’s start with user profiles and content:

  • Users can host their own profiles and content, or sign up with a service provider that hosts several users
  • Users can create a basic profile, which includeAll Postss their name, date of birth, and other basic biographical data
  • When they publish content, it is added to their personal timeline, and an event is shared with their connections notifying them of the new content

How do user connections and sharing work?

  • Each user maintains one or more lists of connections – for example, they may have a “friends” list, and a separate “colleagues” list
  • When they share content to a particular list, an event notification is shared with all the members on that list
  • Sharing of events can use a polling model where users poll for new events from their connections
  • alternatively, sharing can use a publish/subscribe mode – in this case, users can subscribe to one of their connection’s events so that events get published to them

How do users protect their content?

  • When a user publishes content, it is given a unique ID, and is encrypted with a unique key for that piece of content
  • The event notifications sent out for that content has a reference to the content’s unique ID
  • The consuming application uses the content ID to ask the publisher for the symmetric key it can use to decrypt the content
  • Once it has the symmetric key, the consuming user can access the content
  • The publishing user may subsequently refuse to give out the key for a particular piece of content (revoking access)

What all gets protected?

  • We protect the user’s profile information (portions of this are given unique IDs), as well as any content the users generate – this may include status updates, longform text, links, photos, location updates, etc.
  • Users may opt to make any of their content accessible publicly – in this case, it does not get encrypted

Content mirroring, not racking up a view count

  • The encrypted pieces of content, identified by unique IDs can be mirrored by public mirrors or private mirrors – since the data is encrypted, only those who obtain the proper symmetric key can decrypt the content
  • Consumers can choose to access content directly from a publisher, or through a public mirror
  • Public mirrors would be expected to not make view counts available on pieces of content

What are the potential weaknesses and exploits? Leave your thoughts as a comment