On Aug 17, 2011, at 10:35 AM, Jason Smith wrote:
> On Wed, Aug 17, 2011 at 9:18 PM, Adam Kocoloski <[email protected]> wrote:
>> I believe the _security object should be versioned in order to ease
>> synchronization of the object between databases. This proposal is motivated
>> (unsurprisingly) by BigCouch, which typically stores multiple copies of each
>> database in a multi-master configuration. When the _security object is
>> written in BigCouch the update is issued to all available shards. We run
>> into problems if an update is issued while some shards are unavailable,
>> because we don't know how to synchronize the divergent copies once all the
>> shards are back online.
>>
>> In my head I see us representing the _security object using a
>> #full_doc_info, just as we would a document. Unlike documents the _security
>> object (or a pointer to it) would still be written in the header of the
>> database for fast access during request processing.
>>
>> I haven't quite decided what I think the API should look like, e.g. whether
>> the full document API (including attachments?) should be supported. Regards,
>
> In the spirit of re-using existing working components:
>
> How do you feel about migrating to a blessed _local/security document?
> Maybe its latest version could be cached in the header for speed?
>
> Pros:
>
> * Couch gets (conceptually) simpler rather than more complex
> * It's versioned, you get full doc semantics
> * It doesn't replicate, but 3rd-party tools can pseudo-replicate it as needed
> * Design documents can enforce policies: if(doc._id == _local/security
> && doc.members.length == 0) throw {forbidden:"This database may never
> be public"}
>
> Eagerly awaiting a list of cons :)
The only trouble I have with _local/security is that _local documents are
represented using #doc records instead of #full_doc_info records. As such,
they have no support for MVCC. If we managed to get into a situation where the
copies of the _local/security document had really diverged (instead of one copy
simply missing some updates), we'd have a difficult time merging those
conflicting versions.
On the other hand, the challenges I'm having with _security happen with any
_local document, too. Perhaps the right approach is to upgrade the storage
format for the local tree to use #full_doc_info and store the _security object
as a _local document like you suggest (cached on opening the database, of
course).
> Since the _security object is conveniently glued to databases but not
> replicated, I have been tempted to overload it to store per-database
> security settings. There is the CORS discussion, but even simple
> stuff:
>
> { "admins": {"names":[...], "roles":[...]}
> , "members": {"names":[...], "roles":[...]}
> , "read_only": true
> , "create_only": true
> , "delete_only": true
> , "changes_only_allowed_on":"thursday"
> }
>
> // validate_doc_update
> function(newDoc, oldDoc, userCtx, secObj) {
> // read_only, create_only, delete_only obviously aren't true at the
> // same time, just making a concise example.
>
> // Read-only example
> if(secObj.read_only)
> throw {forbidden: "This database is read-only"};
>
> // Create-only example
> if(oldDoc && secObj.create_only)
> throw {forbidden: "This database is create-only"};
>
> // Delete-only example
> if(!newDoc._deleted && secObj.delete_only)
> throw {forbidden: "This database is delete-only"};
>
> // Changes only allowed on Thursday left as an exercise.
> }
>
> However I have not done that because I'm not sure if it is "with the
> grain" in CouchDB. Maybe these are best swallowed up into the ddoc
> itself. (But then when I replicate, now I have to quickly update that
> ddoc for that database's security environment.)
I have no qualms about adding that sort of information to _security. Regards,
Adam