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