JSON forms

March 1st, 2007

I’ve been thinking about how to use JSON as a data interchange format using XRI identifiers and IRAs. You have to love a protocol that can be specified on one page, and there are some compelling reasons to use JSON as an alternative to XML for this purpose. Since XRI data interchange has been known as XDI, I’ll call this JXDI.

This will be a resource-oriented protocol (i.e. REST for the irreligious). Let’s assume that all interactions must be authenticated.

When we authenticate an HTML based interchange, we assume that the client has previously registered with the server, and possesses an identifier (user name) and password that will be recognized by the server. The client supplies these credentials, and if successful receives a header value (a cookie) that will be used to maintain authentication state on subsequent transactions.

JXDI authentication is somewhat analogous. There must be a pre-existing registration process. JXDI is a back-end process happening between two servers, generating an exchange of data that can then be processed for human consumption if desired. Since these are two servers talking to each other, the registration process will consist of the exchange and acceptance of public keys and corresponding XRI identifiers. We’ll worry about how that exchange happens later—it could be some manual administrative process, or possibly XRI trusted resolution or something like it but simpler. We’ll use OpenSSL X509 certs, since the means to generate those is well supported.

Authentication could then happen in several ways. The simplest is for the client to pass an XRI identifying itself, a timestamp, and a PK signature over those two values concatenated. The server, upon verifying that the signature validates with the cert on record for that XRI, issues an opaque session value which the client can use in the header of subsequent requests to authenticate itself for some limited period of time. This is analogous to logging in and receiving a session cookie, and should happen over HTTPS to protect the transaction and also authenticate the server to the client.

A more complex scheme would require as part of client registration that the client certificate be returned signed by the server, so that two-way SSL authentication could happen, passing off the session maintenance to the SSL protocol itself.

So having established a session, let’s do a GET request for the profile data of user with an i-number of ”!1234” and it looks something like this:

GET /profile/!1234.json

The “dot json” extension is a Rails-ism that can be understood in a Rails app to be a request for a response in JSON format. The same thing could be accomplished (less elegantly) with an Accept header.

The response is a JSON form, which unserializes to a data structure (hashes and arrays). It includes one or more fields for the IRAs under which all or various parts of the requested data are available—actually, the pointers (URIs) to those IRAs. The rest of the structure has leaf nodes which at this point are either empty strings (””), zeros for numbers, false for boolean values or null for untyped values. These leaf nodes are the placeholders for the actual data values to be transferred.

This gives the requester two things, the IRA under which the requested data is available, and the data structure and data types in which the data will be delivered—the schema.

To agree to the IRA and receive the data, the requester simply POSTs back to the same URL with the following in the body of the post—

data:JSON string
id:XRI
ts:timestamp
sig:"signature over data+id+ts"

This request, including the signature, is retained by the server to prove that the client agreed to the IRA.

The data is either the whole schema or whatever part of it is desired, but always includes the IRA that covers that part of the schema. The server then returns another JSON form which is the requested schema with the leaf nodes (the actual data) filled in and the IRAs that apply. This JSON form is of course returned as a JSON serialized string, and along with it is a timestamp and a signature with the server’s private key over the JSON string and the timestamp, which the client can retain as proof that the server provided this data under the enclosed IRA.

This should provide all of the elements necessary for a socially enforced data-exchange/reputation network and be simple and comprehensible to boot. No XML parsing (or <shudder>DSIG</shudder>) required! JSON is a very efficient serialization scheme, and unserializes directly into a data structure native to whatever programming language is being used on either end of the exchange.

Even more importantly, this is a highly evolvable procedure.