<aside> 💡 The interface description is for an earlier version of the system. There are a few recent updates which will be soon update to this doc.

</aside>

CoLink Programming Abstractions

In this section, we explain the gRPC endpoints defined by CoLink server to support various abstractions. To reduce the learning efforts, we maintain a minimal set of 14 endpoints, including

Next, we describe those endpoints in detail. Note that the CoLink SDKs expose the same interface in the target programming language.

Connection and User Authentication

CoLink uses JSON Web Token (JWT) for client authentication and TLS for server authentication with a mutual TLS option. JWT contains both a user ID and its role, which could be the administrator (admin), a normal user, or a guest. When the CoLink server starts, it stores a default admin JWT to a location that only the infrastructure manager could access.

    1. RequestCoreInfo(): Serving as a liveness checking endpoint, RequestCoreInfo provides the basic background information about the current server, including the public key of the server and the URI for the message queue. Note that it is the only endpoint that does not require any JWT.
  1. 2.ImportUser(UserConsent): Decided to host data on the server, the user constructs a user consent by signing the public key of the server and asking the admin to submit an ImportUser request with admin JWT on behalf of them. The returned user JWT is used in the following operations.
  2. 3.RefreshToken(ExpirationTime): This endpoint allows both the admin and users to refresh their JWT token updating the field of the expiration time.

Storage

CoLink maintains an internal in-memory key-value storage for both user data and server status. There are two major difference between a normal key-value storage and CoLink storage. First, CoLink maintains the complete history for all storage entries, implying that the deletions are only special update operations. To reflect this difference, each storage entry has a KeyPath which uniquely identifies an immutable value and a KeyName that points to the value for the latest KeyPath. Specifically, KeyPath takes the form of UserID::layer1:...:layerN:varname@timestamp and layer1:...:layerN:varname is the KeyName.

  1. 1.CreateEntry(KeyName, Value): It creates a new entry in CoLink storage. Specifically, it uses the current timestamp and the user ID loaded from JWT to construct a KeyPath and inserts the value. The endpoint returns the contructed KeyPath.
  2. 2.ReadEntries(ListOfKeys): Returns the values in a list of KeyNames or KeyPaths. For KeyName inputs, it find the latest matching KeyPath and return it along with the value inside.
  3. 3.UpdateEntry(KeyName, Value): Add a new KeyPath with the latest value for the KeyName. It creates a new entry if the KeyName does not exist.
  4. 4.DeleteEntry(KeyName): Instead of removing the value completely, DeleteEntry only redirects the KeyName to an empty location. Whoever knows the KeyPath will still have access to the value.
  5. 5.ReadKeys(Prefix, IncludeHistory): In addition to the basic CRUD operations, ReadKeys further allows user to iterate through a sub-space in the storage specified by a give prefix. The boolean flag IncludeHistory indicates whether the return is in the KeyPath or KeyName level.
  6. 6.Subscribe(KeyName, StartTimestamp): Subscribe allow users to monitor the state changes on the server. By specifying the storage entry to be monitored, the server returns a MQ handler that contains messages related to all changes for the given KeyName after a certain StartTimestamp, avoiding the resource consuming client-side polling.
  7. 7.Unsubscribe(Handler): If the user no longer cares about a specific subscription, Unsubscribe helps reduce the server burden of monitoring the changes and sending message for notifications.

Decentralized Task

CoLink provide an abstraction of decentralized task. It contains a TaskID, the protocol type, participant and their roles in the protocol, and many other metadata. The status of the tasks are maintained in the storage and can be accessed by the storage operations discussed above. Protocol operators get updates about incoming task execution request by subscribing to a special storage location.

  1. 1.CreateTask(Task): The initiator specifies the task details. CreateTask helps the user initiate the task and send invitations to other participants.
  2. 2.ConfirmTask(TaskID, Decision): After receiving task invitations and viewing their details from the storage, a user may use ConfirmTask to approve, reject, or ignore a task invitation. If the task is set to require a confirmation, it only starts after all participants have confirmed and approved the task.
  3. 3.FinishTask(TaskID, Status): Users can use FinishTask to mark that a task is finished after following through the complete execution of the protocol.

Inter-server Task Synchronization

Before inter-server synchronization, the receiver needs to generate a guest JWT using their user JWT and share it with the sender for authorization.

  1. 1.InterCoreSyncTask(Task): There is only one endpoint for inter-server task synchronization that serves multiple purposes. If the receiver does not have the task stored before, the request is regarded as a task invitation. If the receiver knew about the task, the request should contain signed decisions to update the task record kept by the receiver.