I did some brainstorming with @larry about supporting collections with the simple Gaia permissioning model we have today.
Collections Background
The idea is that a collection is a user-owned bucket of data which is writable and readable from different applications, each of which will need to ask permission for the bucket. Users will be able to revoke that permission from their browser.
Collections-specific Private Key
The first part of the design is to instantiate a derived private key unique for the collection (say skCollection
).
Now, to write to that collection, we need to use an authentication token:
token = SIGN(challenge-text, skCollection)
We want to deliver that to applications — so when an application requests permission for a collection, the Blockstack Browser can sign the challenge text and give the token to the application.
Unfortunately, this makes revocation impossible — the user would simply have to wait until the token expires (because the challenge text has changed).
Revoking Collection Authentication Token
Authentication tokens can be forced to expire. Basically, if the challenge text contains an integer, then the user can revoke all outstanding tokens by bumping that integer. This does require some metadata on the gaia hub to track the current integer, but I do think that there’s a relatively elegant way to implement metadata.
So, the challenge text generated by the gaia hub would be something like:
{ CUSTOM_GAIA_HUB_TEXT, EXPIRE_DATE, GENERATION_INTEGER }
The integer can be bumped by the Blockstack-Browser everytime the user wants to revoke collections access for a given application. But now all tokens are invalid. Does the user need to re-authenticate to all of these apps now? Can we avoid that? That depends on how the collection authentication token can be passed to the application.
Passing the Collection Authentication Token
If, instead of passing the collection auth token to apps during the authentication process, we pass it by storing it at a well-known location in the application’s data store, the blockstack browser can proactively update the auth token for all the different applications.
This means that the collection authentication token for an application X would be stored in a file:
${gaia_hub_url}/${application_address}/.collections.json
Then, when the blockstack-browser invalidates all of the credentials, it can re-sign the challenge token and write it to that location for each application that should still have access. The blockstack-browser can write to all these locations because it possesses the user’s root-key, so it can always write to application-addresses.
Metadata for Gaia Buckets
A user needs to be able to update that generation integer for a gaia-bucket, and it needs to be persisted. This can be stored in a metadata location within the gaia bucket, however, we want to make sure that the metadata location isn’t writable by arbitrary applications with the collection authentication token, but only by a requester who really owns the private key for the bucket.
This could be implemented by requiring a stronger challenge text for writes to files with a prefix '.'
— and then the gaia hub would read the generation integer for a gaia-bucket from .auth_generation
if it exists. This would need to then be part of ‘in-spec’ behavior of the gaia hub.