RemoteStorage-2012.10

From Unhosted Web Community Group

proposed changes compared to 2012.04 version

the idea for the 2012.10 version of the remoteStorage spec is to add a way for a launch screen app to hand out and revoke access tokens to/from all other apps. These would be derived from a sort of master token, for instance a token for an 'authorizations' scope

two options

we can stay close to OAuth or make our protocol more specific. Staying close to OAuth would probably lead to a cheaper security audit, while going more specific would probably lead to a better and simpler protocol.

things we want to add

the authorizations scope would allow the launch screen app to create and revoke authorizations. If an authorization exists for a certain client_id which was pre-registered with a certain redirect_url, then when this app will later do its OAuth dance, it will work instantly (splash the page and be connected). The same API would allow for listing all current authorizations (installed apps) and revoking. This could work if we pre-register each possible redirect_uri as a client_id.

making it nicer

  • lose the splash screen by passing the derived token through the launch screen app
  • lose the client_id and client registration
  • lose the token expiry

flows

When arriving at an app (we can also skip this one):

  • an app that is visited with no state will display the option to go to the launch screen app

When arriving at the launch screen app:

  • the launch screen app with no state will display the storage discovery. this should no longer require a webfinger user address, but rather combine with nascar

When arriving at the storage:

  • you OAuth the launch screen app once, with its bearer token. this would be the only time you actually do a proper OAuth dance.

Once you have the launch screen app connected:

  • you launch apps from the launch screen, and install them and uninstall them, for which the launch screen app uses its master token

ETag header

Currently a client that wants to request only a path, say "/foo/bar" needs to do a preflight request to "/foo/" in order to get the current timestamp of "/foo/bar". This would be unnecessary, if a GET were required to have a ETag header carrying the timestamp (in milliseconds). In turn client code would become cleaner and easier to maintain.

Concurrency control

A scenario like this is currently possible:

  • App A does a GET on path X
  • App B does a GET on path X
  • App A updates data, then does a PUT on path X
  • App B updates data and does a PUT on path X as well

Now the update of A was overwritten.

To prevent this scenario, the storage server has to reject the PUT made by B. To make this work, a PUT (and DELETE) needs to be accompanied by some indication, what version of X the app last saw. I think this could be done using the If-Match header and the value from ETag of the last GET.

Clarification

It needs to be clarified, that parts of paths that are URI-encoded should be displayed in directory listings in the encoded form.

Example:

 PUT /foo/bar%2F
 GET /foo/ -> { "bar%2F": 12345 }

to distinguish from:

 PUT /foo/bar/baz
 GET /foo/ -> { "bar/": 23456 }

At least two storage providers (5apps and remotestorage-ruby) got this initially wrong.

Timestamp format

2012.04 doesn't say anything about the precision of timestamps. However all implementations use milliseconds now. This needs to be mentioned.

Binary data

On the browser side binary data needs to be handled specially (conversion to Blob, base64 encoding for caching to localStorage, etc). To detect whether a response from the server contains UTF-8 or binary data, the "charset" property of "Content-Type" must be set to either "binary" or "utf-8".

Scopes format

To match the way permissions are specified in webAPI manifests, "r" will change to "readonly" and "rw" will change to "readwrite".

Get rid of camelCase in webfinger rel

The remotestorage link in the webfinger profile will change from "remoteStorage" to "remotestorage". Also the "type" needs to be updated to signal support for this spec version.