Hi,
thanks Jason for starting the discussion here. The summary looks great.
On 8 Sep 2009, at 00:50, Jason Davies wrote:
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.
Chris Anderson:
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.
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.
On 9 Sep 2009, at 00:41, Adam Kocoloski wrote:
On Sep 7, 2009, at 6:50 PM, Jason Davies 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.
I think it's actually pretty sensible to store some authz
information in the DB itself, for many of the same reasons outlined
by Brian and Benoit. The big exception there is the ability to
create new DBs. That's traditionally the task of a server admin,
but perhaps we could come up with some special role that could be
granted to users to allow them to do that.
+1
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?
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}
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.
What are the next steps?
Cheers
Jan
--