On Mon, Sep 7, 2009 at 3:50 PM, Jason Davies<[email protected]> wrote: > Hi all, > > There have been sporadic discussions about various granularities of > authorization. The most simple level to tackle is per-db authorization. > What follows is a summary of discussions and ideas so far. > > I should point out that this is primarily to flesh out the default > authorization modules that address the needs of the majority of users. We > probably will have an authorization_handlers settings, analagous to > authentication_handlers, allowing custom authorization modules to be used. > > 1. Where are the permission "objects" themselves stored? The permissions > determine which users can do what with each database. I think storing these > in the per-node users database (called "users" by default) makes the most > sense. We are talking about per-db auth so it wouldn't make any sense to > store this information in the affected databases themselves. > > 2. What types of operations do we need to support? I think the majority of > users will only care about being able to make particular databases > read-only, read/write, or write-only (not sure about the latter one). > > 3. How do we implement these operations using the existing > user_ctx{name=..., roles=[...]} object? I don't think we necessarily need > to set any special roles, although this was my initial thought e.g. > ['_read', '_write'] on a per-db basis. As authorization is a separate > module, we can simply pass the appropriate permission (read and/or write) > through when opening the db internally in the httpd db handler function. > The db-opening function will then need to throw an error if writes are > attempted and it is in read-only mode. Using actual roles is potentially > more elegant, as custom roles could also be set using the permission objects > and implementation might be easier. > > 4. One use-case we need to bear in mind is being able to grant/deny access > to sets of databases at a time. One way to do this would be to allow > patterns to be specified, for example: > > { > "_id": "foo", > "type": "permission", > "username": "jason" > "match": "jason/*", > "operations": ["_read"] > } > > This would grant the user "jason" read-only access to any database that has > the prefix "jason/". > > 5. Permissions per roles vs permissions per users? Although the above > example specifies access for a particular user, it might be more elegant and > efficient to do this per role instead. If per user is needed this can be > done by giving the user a special role unique to them. If a user has > multiple roles then we would take the union of the resulting permission set. > > 5. Default settings: we already have the require_valid_user setting, which > forces a node to authenticate users. We would need to support certain > access permissions for non-logged-in users i.e. anonymous users. This could > be done using a special "_anonymous" string in the permission to override > the default, which would probably be read/write for everyone as it is now. > > 6. Future work: thisfred suggested that the pattern-matching could be > extended to the full URL instead of just the database name. This seems like > a simple way to extend authorization. Of course, it's dependent on a > particular node's URL mappings (these can be changed in the .ini). This > then brings up the question of what the operations should be, it would make > the most sense to let them be HTTP verbs, so that one could restrict access > to certain URLs to being only GET and HEAD for example. This seems a bit > too tied to HTTP for my liking, but I guess CouchDB is very much a RESTful > and therefore HTTP-reliant database. Any further ideas would be welcomed. >
Thanks Jason, overall good analysis. Way to go in depth here. If I were writing the code I'd start with the simplest thing that can possibly work, which is making the _admin role available to users on a per-db basis. I think this would involve some but not all of the mechanics you describe, and it extends the current model, so it seems like a good start. I think building RESTful assumptions into our default authorization model is perfectly reasonable. I agree the tie to HTTP is a smell, but I'd call it a good smell. Chris -- Chris Anderson http://jchrisa.net http://couch.io
