An Agile Approach to Self-Sovereign Identity

As a perpetual optimist I remain hopeful in the promise of technology, but I am not blind. I see how destructive technology has been to our lives and our community. Self-sovereign identity (SSI, outlined here: is perhaps the source of my optimism. With this, I can imagine a world where technology isn't a tool to manipulate us for profit and control, but instead a tool to actually better our lives.

I have spent this pandemic year with my friend imagining this alternate world. The result is this project, which may end up simply as a great learning experience, but I feel has the potential to grow into something much bigger. While SSI is the vision for the project, the thesis of the book Lean Startup helped guide us through some of the tougher design decisions. The book argues the case for getting an implementation of our vision in front of the target users as quickly as possible and then iterating on that implementation. This is consistent with agile programming, which approaches a project in thin vertical slices and then expands out horizontally.

Slice 1: Dikota

Our first slice was the simplest app we could think of that would still provide some value, a contact app, Dikota. It allows a user to setup a profile and enter their contact details. It also allows a user to discover other identities and synchronize their contact details. Lastly it implements access control where the user labels their contact details as well as the other discovered identities. The other identities are only be able to access the details with a matching label.

Screen 1 - Dikota Home Screen: Contacts are presented in a list with buttons for SMS, Phone, and Email. Screen 2- Account Profile: Users can populate their public profile as well as their contact attributes. Screen 3 - Labels: Users can label their attributes to determine who can access them. Screen 4 - Search: Other users of Dikota can be searched based on their public profile. Screen 5 - Contact Profile: Contacts can be labeled according to the attributes they will granted access when connected.

To support this app, we needed to implement a distributed network that implements a simplified data model for digital identity. Each identity has contacts, attributes, labels and a public profile. Contacts can be connected, which allows specifically labelled attributes to be retrieved. The node for this distributed network became the project CoreDB.

We wanted to support the ability for identities to relocate and provide a human readable unique handle, so for this we added a public registry. The public profile specifies the node URL hosting the identity as well as a unique handle, and is kept synchronized with a public registry. To change nodes or the handle, the identity owner simply needs to update the registry.

To support the search functionality of other identities, we added an app server for Dikota. It stores a copy of the public profiles of all Dikota users and provides a search mechanism through those fields. As an interesting feature, we added the ability to post your GPS location and search for others who recently posted their GPS location.

Network Architecture for Dikota: The mobile app communicates with three network entities; the CoreDB app server hosting the identity, a Registry service providing a link to the identities, and a Dikota app server to provide search capabilities.

Slice 2: Jupstream

For the next app, wanted to allow users to share photos, videos, and audio, and we called it Jupstream. It also supports labels, granting access to the media only to contacts with matching labels. With access, other contacts are also be able to comment on the media.

Screen 1 - Jupstream Feed: Posts from your contacts are aggregated into a chronological feed for you to view. Screen 2 - Image: A user can post an image to their stream. The image is labelled according to the contacts who should have access. Screen 3 - Video : A user can post a video to their stream. The video is labelled according to the contacts who should have access. Screen 4 - My Stream: While the post is uploading and processing, it will be represented with a placeholder image. The action bar is blue to indicate an upload in progress. Screen 5 - My Stream: When the posts have finished processing, they can be viewed just like the stories from other contacts.

To support this app, the data model was extended with subjects and tags. Subjects are attributes that can additionally have files, tags and an expiration associated. Tags are simple objects that can be posted by other contacts. To make the media files accessible, the media files are processed on upload. All metadata is stripped for privacy reasons, and the files can be resized to be used in different contexts. Images for example can be scaled and cropped, and videos can be transcoded to different bitrates.

For Dikota, we could host the full identity network at very little cost, but with the introduction of photos and video, this was no longer possible. We needed users to host their own identities and perhaps the identities of their friends and family. To help with this process, we created a portal to help in the node management. It assigns hostnames as well as provide a web interface to manage the nodes.

Network Architecture for Dikota and Jupstream: Once media was added to the network, the identity nodes were reduced in size to be owned and managed by users. A Portal was added to simplify the node management for the users. A Jupstream app server was added to store app settings for the users, for example default playback quality.

Slice 3:

We now need to decide what the next slice should be. Here are a couple of our initial thoughts, but we would love ideas from the community.

  • Private Messaging - Built on an identity network, a messaging app can achieve a very high level of privacy with no intermediate servers. Messages would be sent directly from an app to the contact’s identity.
  • Useful Reviews - Reviews collected from only your contacts could actually be useful, unfortunately there wouldn't be too many. Instead however, if the reviews were collected from contacts with N degrees of separation, the reviews would likely still be useful and an exponentially greater number.

Design Considerations:

A tough decision we took early was to not leverage the Solid Project. Their knowledge base and experience is far beyond our own, but following agile principles, we needed a very simple data model. As Ruben Verborgh's blog points out (, the focus has been on back-end systems. While the javascript libraries make Solid Project more accessible to front-end developers, the data model was more complex than we needed and maybe more than we could handle.

Some people may feel blockchain is an ideal solution for distributed identifiers, but the complexity of blockchain is significant, and the needed functionality could be achieved in other ways. Also, its large carbon footprint makes for a poor long term solution. By using the fingerprint of a public key as an identifier, authentication of entities can be achieved, and a simple public registry can provide the lookup of those identifiers.


This project has been a great experience so far, so we plan to continue for the foreseeable future. Please feel free to give feedback, join the network or contribute to our Github repository.


project webpage:

github repository:

coredb installer for ubuntu 18.04:

installation instructions:
raspberry pi -
aws  -

dikota mobile app:
ios -
android -

jupstream mobile app:
ios -
android -

Roland Osborne

Roland Osborne

San Francisco