On Sep 11, 2009, at 9:43 AM, Jan Lehnardt wrote:

The only nagging thought that keeps popping up in my head is that users might think of read access as granting GET. But then we use POST for multi-key get in views. Just something to be aware of I guess.

It's a good point. Kinda unfortunate that we felt compelled to use POST in this way.

On 9 Sep 2009, at 00:41, Adam Kocoloski wrote:

On Sep 7, 2009, at 6:50 PM, Jason Davies wrote:

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).

I think write-only is a keeper. It may also be useful to distinguish between creating new documents and updating existing ones. For instance, SQL GRANT tables distinguish between INSERT and UPDATE.

validate_doc_update = function(doc, req) {
 if(doc._rev) {
   // handle update
 } else {
   // handle insert
 }
}

Am I missing something?

I guess that's ok. I was writing in the context of built-in write restrictions -- I'm a bit worried about the performance of validate_doc_update functions, and if we're doing built-in reader lists we might as well do built-in writer lists, too.

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.

So, after giving this some thought I'm partial to the idea of Access Control Lists. Instead of directly granting privileges on databases in the users DB, we'd store an ordered list in the DB in a special document that would allow|deny requests that match a rule. For instance, if I wanted to make a read-only DB where only I could access the _design documents I could upload a document like

{
  _id: "_authorization",
  _rev: "1-1340514305943",
  _acl: [
{"access":"allow", "role":"kocolosk", "method":"*", "path":"*"}, {"access":"deny", "role":"*", "method":"*", "path":"_design*"} {"access":"allow", "role":"*", "method":"GET", "path":"*"}, {"access":"deny", "role":"*", "method":"*", "path":"*"}
  ]
}

The rules in the ACL array are applied in order, and the first rule to match wins. Here I've assumed that my user has a corresponding role, like a UNIX group.


I like the ACLs. We can parse the JSON into Erlang matching patterns once and and use then from there. I'd prefer that over Brian's possible solution of having another JavaScript function for this.


Benoit mentioned that he wanted authz to replicate. If we decide that's the way we want to go, storing the ACL in a regular document with a reserved ID would allow for that. If we didn't want it to replicate, we could just change that docid to something like _local/ authorization

As with history, I could see we'd want a document type that is a hybrid of a regular doc and a _local doc, say _db/ for example, that can be replicated conditionally with

POST /_replicate
{source:..,target:...,replicate_db_doc:true}

Interesting idea. I imagine that in the implementation these would be regular documents, but with pattern-matching filters in the replication framework.

We might take this one step further and allow additional Access Control Elements in individual documents. These ACEs would be prepended to the DB ACL and would allow you to specify custom authz for a subset of documents in a DB without having to resort to path- based regex and editing the DB ACL every time.

Sounds complicated. -1

Finally, there's the issue of authz in views. What privileges does the view indexer have? If a user who is only allowed to read some of the documents in the DB is allowed to upload a _design document, it seems to me that the views generated from that _design document must exclude any forbidden documents. I guess this can work if the _design doc stores the roles of the user who saved it. It seems like a tricky, but solvable problem.

So far we don't have the notion per-doc ACL's. So a user can read all docs in the DB or none, but not some. If we'd go there, I think users that can modify design docs are higher in the auth* chain than users that only can read some documents and thus inherit the role of read-all-docs.

That's true, if per-document ACLs are a -1 as you indicated above then view security becomes far simpler. Does it mean you're also -1 on the path-based regex in the ACL example I wrote? Because that's just an alternative implementation of per-document ACLs.

Best, Adam

Reply via email to