Details

    • Type: New Feature New Feature
    • Status: Open
    • Priority: Minor Minor
    • Resolution: Unresolved
    • Affects Version/s: 1.2
    • Fix Version/s: None
    • Component/s: HTTP Interface
    • Labels:
      None
    • Skill Level:
      New Contributors Level (Easy)

      Description

      Currently, we can only grant combined read+write access in the _security object "members" section. A user can either do both or neither. This prevents a very common requirement for couch apps: sending private information from less-privileged users to more-privileged users.

      There is no (reasonable) way to make an "inbox" where anybody may create a doc for me, but only I may read it. An inbox database allows user-to-user, or user-to-admin private messages. (Not only chat messages, but asynchronous notifications--with a per-user inbox, perhaps even service requests and responses.)

      There is no reason _security.members (formerly .readers) should control write access. validate_doc_update() functions do this better.

      I propose a boolean flag, _security.members.allow_anonymous_writes. If it is true, then CouchDB will allow document updates from non-members, giving validate_doc_update() the final word on accepting or rejecting the update.

      Requirements:

      1. Everything about _security stays the same (backward-compatible)
      2. If members.allow_anonymous_writes === true, then most PUT and POSTs may proceed
      3. All updates are still subject to approval by all validate_doc_update functions, same as before.

      These are the known changes to the security model. I consider these all to be either very unlikely in practice, or worth the trade-off.

      • If you write to an inbox DB, you know, for a time, a subset of its documents (but that's the point)
      • An _update function could reveal a document to the user, with or without changing it. However, an admin must install such a misguided update function.
      • You can launch timing attacks to learn information about validate_doc_update
      • You might discover whether doc IDs exist in the DB or not
      • You might discover a well-known open source validation function. You can look for bugs in its source code.
      • Zero or more things which Jason can't think of

        Activity

        Hide
        kowsik added a comment -

        Just a dumb question, that maybe outside the scope of this write-only mode. Is there a way to use the update/validate handlers to rate-limit and or restrict the writes in some ways? Given the writes are effectively coming from an untrusted source, it won't take long to fill the disk very quickly.

        Show
        kowsik added a comment - Just a dumb question, that maybe outside the scope of this write-only mode. Is there a way to use the update/validate handlers to rate-limit and or restrict the writes in some ways? Given the writes are effectively coming from an untrusted source, it won't take long to fill the disk very quickly.
        Hide
        Jason Smith added a comment -

        Kowsik, this has long been a CouchDB DOS vulnerability however inbox databases do not change the situation.

        The real world has and needs side-effects. You post a comment. You post a comment. You post a comment; and now there is a CAPTCHA. You fail. You fail. You fail; and now your IP address is blacklisted.

        As with many problems, the solution is not too bad with a "2.1-tier" CouchDB architecture. Watch your logs for activity and update either the database _security object, or else the design document with e.g. update rates. Next, validate_doc_update() can simply confirm that this class of update has not exceeded its rate.

        In any case, yes, IMHO it is out of scope here.

        Show
        Jason Smith added a comment - Kowsik, this has long been a CouchDB DOS vulnerability however inbox databases do not change the situation. The real world has and needs side-effects. You post a comment. You post a comment. You post a comment; and now there is a CAPTCHA. You fail. You fail. You fail; and now your IP address is blacklisted. As with many problems, the solution is not too bad with a "2.1-tier" CouchDB architecture. Watch your logs for activity and update either the database _security object, or else the design document with e.g. update rates. Next, validate_doc_update() can simply confirm that this class of update has not exceeded its rate. In any case, yes, IMHO it is out of scope here.
        Hide
        Benoit Chesneau added a comment -

        @kowsic that's another topic. But indeed you can use validate update function to forbid doc insertion. You can do it by checking the user doc. Throttling protections and such however can be added using authenticate module eventually or any other system.

        Show
        Benoit Chesneau added a comment - @kowsic that's another topic. But indeed you can use validate update function to forbid doc insertion. You can do it by checking the user doc. Throttling protections and such however can be added using authenticate module eventually or any other system.
        Hide
        Jason Smith added a comment -

        Proposed implementation attached.

          1. Notes

        It would be nice to have _security.readers, _security.writers, and maybe sugar _security.members which implicitly populates both. A write-only DB would have _security.readers = {}, security.writers.roles = ["_anonymous"]. However this patch maintains compatibility with the 1.x codebase. (I tagged it v2.0 because v1.3 is not an option.)

        The patch is not correct. Really, couch_db:open is an inappropriate place to assess authorization. Couch must know what the request will do before it determines authorization. It is unsafe to evaluate permission until execution enters the ultimate, true request handler. (Note that couch_db:check_is_admin/1 is sprinkled everywhere. Same deal.)

        A more correct patch is more substantial; but substantial code changes is itself a security risk. I opted for the simpler way: whitelist a few good requests based on the method #httpd.path_parts. IMO, this implementation is fail-safe. Unexpected changes or execution isn't likely to grant access. (The couch_db:check_is_admin/1 stuff is fail-unsafe; we must remember to call it every time we change the code.)

        Show
        Jason Smith added a comment - Proposed implementation attached. Notes It would be nice to have _security.readers, _security.writers, and maybe sugar _security.members which implicitly populates both. A write-only DB would have _security.readers = {}, security.writers.roles = ["_anonymous"] . However this patch maintains compatibility with the 1.x codebase. (I tagged it v2.0 because v1.3 is not an option.) The patch is not correct. Really, couch_db:open is an inappropriate place to assess authorization. Couch must know what the request will do before it determines authorization. It is unsafe to evaluate permission until execution enters the ultimate, true request handler. (Note that couch_db:check_is_admin/1 is sprinkled everywhere. Same deal.) A more correct patch is more substantial; but substantial code changes is itself a security risk. I opted for the simpler way: whitelist a few good requests based on the method #httpd.path_parts. IMO, this implementation is fail-safe. Unexpected changes or execution isn't likely to grant access. (The couch_db:check_is_admin/1 stuff is fail-unsafe; we must remember to call it every time we change the code.)
        Hide
        Benoit Chesneau added a comment -

        @jason Thanks for the implementation patch. I had a quick look about it. But indeed couch_db:* isn't an appropriate place for that imo, it shouldn't know anything about #httpd{} imo, passing it in the req option is awkward.

        Maybe we could go to a simpler way ? I was thinking we could allows any readers to do anything but just accept PUT /db/docid and POST /db

        {...}

        so no handlers at alls. Which make the test easier imo since you only have to test for "<<"_", _/binary>>. Also rewrite should be disabled for non readers.

        Thoughts?

        Show
        Benoit Chesneau added a comment - @jason Thanks for the implementation patch. I had a quick look about it. But indeed couch_db:* isn't an appropriate place for that imo, it shouldn't know anything about #httpd{} imo, passing it in the req option is awkward. Maybe we could go to a simpler way ? I was thinking we could allows any readers to do anything but just accept PUT /db/docid and POST /db {...} so no handlers at alls. Which make the test easier imo since you only have to test for "<<"_", _/binary>>. Also rewrite should be disabled for non readers. Thoughts?
        Hide
        Jason Smith added a comment -

        Thanks, Benoit. These are good points.

        I agree, really the entire execution path is awkward. It deserves a major change to clarify and simplify the security architecture. However, do you agree that such change is not appropriate for the 1.x codebase? That was my feeling, and that is why I adopted the somewhat awkward code. However, the flaw is not fatal.

        Before this patch, HTTP handlers ask the deeper layer (couch_db:open), "Please open the database, and here is some request context, user_ctx, to decide about permission."

        After this patch, HTTP handlers ask the deeper layer (couch_db:open), "Please open the database, and here is some request context, user_ctx, method, path_parts to decide about permission."

        Thus, the patch does not change the situation fundamentally. But you are correct that couch_db:open should not know about #httpd{}.

        What do you think about this instead? It shaves the Options down to only the necessary information:

        couch_db:open(Db, [

        {user_ctx,UserCtx}

        ,

        {method,Method}

        ,

        {path_parts,PathParts}

        ])

        This way, couch_db:open does not have to extract the HTTP information itself. The abstraction barrier is cleaner. We remain foolish (Matt 7:26) but IMO we can still weather the storm

        Finally, why should _rewrite be disabled for non-readers? I rather like your implementation: completely re-build a request object and re-execute. This ensures that nobody can sneak past the defenses by using rewrite: every rewritten request must start from the beginning. For this reason, I do not see a security objection to _rewrite. Do you object on other grounds? (For example, if I succeed in a _rewrite request, then I have learned information about the ddoc)

        Show
        Jason Smith added a comment - Thanks, Benoit. These are good points. I agree, really the entire execution path is awkward. It deserves a major change to clarify and simplify the security architecture. However, do you agree that such change is not appropriate for the 1.x codebase? That was my feeling, and that is why I adopted the somewhat awkward code. However, the flaw is not fatal. Before this patch, HTTP handlers ask the deeper layer (couch_db:open), "Please open the database, and here is some request context, user_ctx, to decide about permission." After this patch, HTTP handlers ask the deeper layer (couch_db:open), "Please open the database, and here is some request context, user_ctx, method, path_parts to decide about permission." Thus, the patch does not change the situation fundamentally. But you are correct that couch_db:open should not know about #httpd{}. What do you think about this instead? It shaves the Options down to only the necessary information: couch_db:open(Db, [ {user_ctx,UserCtx} , {method,Method} , {path_parts,PathParts} ]) This way, couch_db:open does not have to extract the HTTP information itself. The abstraction barrier is cleaner. We remain foolish (Matt 7:26) but IMO we can still weather the storm Finally, why should _rewrite be disabled for non-readers? I rather like your implementation: completely re-build a request object and re-execute. This ensures that nobody can sneak past the defenses by using rewrite: every rewritten request must start from the beginning. For this reason, I do not see a security objection to _rewrite. Do you object on other grounds? (For example, if I succeed in a _rewrite request, then I have learned information about the ddoc)
        Hide
        Jason Smith added a comment -

        Second (series B) patch set. Differences from series A:

        1. Do not send an #httpd{} to couch_db:open/2. Instead, send only the userCtx (as before) plus the method and path_parts.

        2. Allow nonmember POST /db

        3. Allow PUT and POST to _rewrites. (If we decide that is unsafe we can negate the assertions.)

        Show
        Jason Smith added a comment - Second (series B) patch set. Differences from series A: 1. Do not send an #httpd{} to couch_db:open/2. Instead, send only the userCtx (as before) plus the method and path_parts. 2. Allow nonmember POST /db 3. Allow PUT and POST to _rewrites. (If we decide that is unsafe we can negate the assertions.)
        Hide
        Jason Smith added a comment -

        I published the patch set as a branch in GitHub.

        https://github.com/jhs/couchdb/compare/trunk...inbox

        The sole non-housekeeping commit is https://github.com/jhs/couchdb/commit/56a373f

        Show
        Jason Smith added a comment - I published the patch set as a branch in GitHub. https://github.com/jhs/couchdb/compare/trunk...inbox The sole non-housekeeping commit is https://github.com/jhs/couchdb/commit/56a373f
        Hide
        Jason Smith added a comment -

        Pardon. Cleaning and tagging for (hopefully) v1.2.

        Show
        Jason Smith added a comment - Pardon. Cleaning and tagging for (hopefully) v1.2.
        Hide
        Benoit Chesneau added a comment -

        @Jason

        I'm not sure what is the intention of the patch reading the code. An inbox db or rather a dropbox db should only accept doc creation, then only admins of the db or eventually readers can read them. Here it seems that you can still have a design doc to handle some actions which could pretty dangerous.

        Second, I think testing methods based on paths is awkward. If people are using modules or externals, it means that they have to test by themselves if the method is allowed or not which could become a problem. I think a dropbox db should be handle at db level and not HTTP level.

        Show
        Benoit Chesneau added a comment - @Jason I'm not sure what is the intention of the patch reading the code. An inbox db or rather a dropbox db should only accept doc creation, then only admins of the db or eventually readers can read them. Here it seems that you can still have a design doc to handle some actions which could pretty dangerous. Second, I think testing methods based on paths is awkward. If people are using modules or externals, it means that they have to test by themselves if the method is allowed or not which could become a problem. I think a dropbox db should be handle at db level and not HTTP level.
        Hide
        Benoit Chesneau added a comment - - edited

        This is an alternative patch handle dropbox db:

        Add dropbox: true to security object. Only admins and db admins can read docs. Anyone can post a doc. No test for now I will add it later today. It's already used in refuge.

        Here is how it works:

        PUT http://localhost:5984/_security -d'

        {"dropbox": true}

        '
        -H'Content-Type: application/json'

        test it :
        curl -XPUT 'http://admin:test@127.0.0.1:5984/testdb/1' -d'

        {"a": 1}

        '
        -H"Content-Type: application/json"

        curl -XGET http://127.0.0.1:5984/testdb/1

        {"error":"unauthorized","reason":"You are not a db or server admin."}

        curl -XGET http://admin:test@127.0.0.1:5984/testdb/1

        {"_id":"2","_rev":"1-3975759ccff3842adf690a5c10caee42","a":1}
        Show
        Benoit Chesneau added a comment - - edited This is an alternative patch handle dropbox db: Add dropbox: true to security object. Only admins and db admins can read docs. Anyone can post a doc. No test for now I will add it later today. It's already used in refuge. Here is how it works: PUT http://localhost:5984/_security -d' {"dropbox": true} ' -H'Content-Type: application/json' test it : curl -XPUT 'http://admin:test@127.0.0.1:5984/testdb/1' -d' {"a": 1} ' -H"Content-Type: application/json" curl -XGET http://127.0.0.1:5984/testdb/1 {"error":"unauthorized","reason":"You are not a db or server admin."} curl -XGET http://admin:test@127.0.0.1:5984/testdb/1 {"_id":"2","_rev":"1-3975759ccff3842adf690a5c10caee42","a":1}
        Hide
        Benoit Chesneau added a comment -

        oops the patch based on couchdb. replacing previous one which was based on refuge code.

        Show
        Benoit Chesneau added a comment - oops the patch based on couchdb. replacing previous one which was based on refuge code.
        Hide
        Jason Smith added a comment - - edited

        Thanks, Benoit. I avoid the word "dropbox" because of confusion with the folder sync service. What would CouchDB users expect when enabling a "dropbox" flag. Jan proposed "allow_anonymous_writes" because it is clear.

        What is the intention of the patch? The most direct answer is the first and second paragraph of this issue description: to send a private message from user A to user B. Without an inbox db, the solution is a shared db for every combination of users, which is (1) impractical, and (2) not scalable. Note also requirement 3: All updates are still subject to validate_doc_update().

        What is going on with your example? Querying /_security gives me illegal_database_name. Did you mean /testdb/_security? This feature is to suspend the security rules. We must be attentive to detail.

        I am interested in your idea about doing this at at the DB level. I avoided this for a debatable reason: I wanted a minimal patch, easy to understand, changing as little as possible. My core code is 20 lines of focused code. It's all in one place. In our brains, it has locality of reference. But I invite you to defend your security trade-off. Now "dropbox-nature" must be considered throughout the code base, even view handlers. Is it easy to get it right? Well, you got it wrong. Make /testdb private by adding a members list. But a database member can query /testdb but not /testdb/_all_docs. Worse, anonymous users can query /testdb! They can see the doc_count and other details. That is a regression. What's going on? I think we are building different, unrelated features, in which case maybe yours can go in a new ticket?

        My patch set includes 50 tests demonstrating what may happen and what may not happen. I included an analysis of the patch's security implications. How about yours? I am thankful for your review. No doubt, you are also sensitive to my frustration: I work hard to contribute to CouchDB, only to see (for the second time) a bigwig committer swoop down, make a quick critique, and post a half-hearted rewrite, showing no evidence of equivalent thoughtfulness and deliberation.

        But where are these modules and externals which I have broken? Are they under the Apache CouchDB project? Is there a plugin policy which I have violated? I am not yet persuaded by vague invocations of externals or module authors. (What is a "module" author anyway?) I am intrigued! But not yet persuaded. It sounds like a convenient hypothetical hurdle.

        Agreed! Testing based on paths is awkward. But: Pattern matching request paths is the fundamental architecture of CouchDB 1.x. Why does that disqualify new functionality? Plugin authors like me[1] already tackle the problem that _admin is the assumed privilege level.

        I find Paul's (anticipated) criticism more compelling: security. My initial implementation was based on HTTP verbs and it was inadequate. Thus, to answer Paul: yes, I am pattern matching; but notice that the patterns are for approval, any non-match, anything unexpected, anything except those situations we have explicitly greenlighted, falls back to the current execution path. So, I share your concern completely, but I hope I've shown that I thought it through, and I consider the risk worthwhile.

        Committers: you are the stewards of a code base built upon pattern matching paths, manually running couch_db:check_is_admin/1 for every possible privileged query. How can you argue against my whitelisted, fail-safe design with a straight face?

        [1]:
        https://github.com/iriscouch/browserid_couchdb
        https://github.com/iriscouch/CouchDB-Facebook-Authentication
        https://github.com/iriscouch/futon_couchdb
        https://github.com/iriscouch/pingquery_couchdb
        https://github.com/iriscouch/die_couchdb
        https://github.com/iriscouch/cgi_couchdb

        Show
        Jason Smith added a comment - - edited Thanks, Benoit. I avoid the word "dropbox" because of confusion with the folder sync service. What would CouchDB users expect when enabling a "dropbox" flag. Jan proposed "allow_anonymous_writes" because it is clear. What is the intention of the patch? The most direct answer is the first and second paragraph of this issue description: to send a private message from user A to user B. Without an inbox db, the solution is a shared db for every combination of users, which is (1) impractical, and (2) not scalable. Note also requirement 3: All updates are still subject to validate_doc_update(). What is going on with your example? Querying /_security gives me illegal_database_name. Did you mean /testdb/_security? This feature is to suspend the security rules . We must be attentive to detail. I am interested in your idea about doing this at at the DB level. I avoided this for a debatable reason: I wanted a minimal patch, easy to understand, changing as little as possible. My core code is 20 lines of focused code. It's all in one place. In our brains, it has locality of reference. But I invite you to defend your security trade-off. Now "dropbox-nature" must be considered throughout the code base, even view handlers. Is it easy to get it right? Well, you got it wrong. Make /testdb private by adding a members list. But a database member can query /testdb but not /testdb/_all_docs. Worse, anonymous users can query /testdb! They can see the doc_count and other details. That is a regression. What's going on? I think we are building different, unrelated features, in which case maybe yours can go in a new ticket? My patch set includes 50 tests demonstrating what may happen and what may not happen. I included an analysis of the patch's security implications. How about yours? I am thankful for your review. No doubt, you are also sensitive to my frustration: I work hard to contribute to CouchDB, only to see (for the second time) a bigwig committer swoop down, make a quick critique, and post a half-hearted rewrite, showing no evidence of equivalent thoughtfulness and deliberation. But where are these modules and externals which I have broken? Are they under the Apache CouchDB project? Is there a plugin policy which I have violated? I am not yet persuaded by vague invocations of externals or module authors. (What is a "module" author anyway?) I am intrigued! But not yet persuaded. It sounds like a convenient hypothetical hurdle. Agreed! Testing based on paths is awkward. But: Pattern matching request paths is the fundamental architecture of CouchDB 1.x. Why does that disqualify new functionality? Plugin authors like me [1] already tackle the problem that _admin is the assumed privilege level. I find Paul's (anticipated) criticism more compelling: security. My initial implementation was based on HTTP verbs and it was inadequate. Thus, to answer Paul: yes, I am pattern matching; but notice that the patterns are for approval , any non-match, anything unexpected, anything except those situations we have explicitly greenlighted, falls back to the current execution path. So, I share your concern completely, but I hope I've shown that I thought it through, and I consider the risk worthwhile. Committers: you are the stewards of a code base built upon pattern matching paths, manually running couch_db:check_is_admin/1 for every possible privileged query. How can you argue against my whitelisted, fail-safe design with a straight face? [1] : https://github.com/iriscouch/browserid_couchdb https://github.com/iriscouch/CouchDB-Facebook-Authentication https://github.com/iriscouch/futon_couchdb https://github.com/iriscouch/pingquery_couchdb https://github.com/iriscouch/die_couchdb https://github.com/iriscouch/cgi_couchdb
        Hide
        Benoit Chesneau added a comment - - edited

        The alternative patch i propose is 49 insertions, 11 deletions, so it's pretty short too. . Also i don't care about having a service named dropbox , the thing is this is a dropbox, but name can be change if most want, that's an implementation detail.

        Yes, it's /testdb/_security . What do you mean by preventing? Only admins can used that and once it's done only admins can change that. Where is the problem? If you want to remove the security object use, not sure why ..., but it should be a different patch. What I would like to see is making this security object optionally replicable (for clusters) but that's another point, another ticket.

        I'm not sure why do you mean when you say I got it wrong. Particularly offensive. What do you mean by query /testdb ? I think you misunderstood the patch.

        The alternative patch forbid anonymous users to query the db which is flagged as dropbox. Only admins car read it (readers can be added if there is a need to). Since anonymous users are forbidden they can't access to design docs so the views (a view imply to read the ddoc). _all_docs is a specific case. It shouldn't be part of couch_mrview in fact but like davisp said there isn't an easy way to separate it from it since we need to parse parameters and such. It will be part of another patch but I intend to propose a patch adding all_docs handling to couch_db module. But _all_docs is forbidden. About the count of db, what's the security issue here? If there is really an issue, a check could be added to dbinfo function too. But you should be aware that it will break then some couchdb clients.

        So here we have a working dropbox. There is no test for now, but this patch is actually used in a real project. Like I said I will add tests today. Also technically speaking this patch is really simple, it doesn't do much than allowing anonymous writes while preventing reading.

        Re security. My criticism are about security too. Testing on path and method is really awkward, it works "mostly" today, but what about the future?. When speaking about externals and other things I'm thinking to people that add plugins to couchdb. This expectation should be taken in consideration. While couchdb can't answers to all needs I see more and more people customizing it, adding plugins and such. We should support that by providing the right api imo. Also I don't want to force users to check that they handle correctly a dropbox feature etc which should be part of the core. That's the point of having it handled at lower level. I'm doing as much pluging as you do, and the more I work on that part, the more I think the couchdb core could simplify the life of these external coders. At a community point of view having more plugins developed is good.

        Show
        Benoit Chesneau added a comment - - edited The alternative patch i propose is 49 insertions, 11 deletions, so it's pretty short too. . Also i don't care about having a service named dropbox , the thing is this is a dropbox, but name can be change if most want, that's an implementation detail. Yes, it's /testdb/_security . What do you mean by preventing? Only admins can used that and once it's done only admins can change that. Where is the problem? If you want to remove the security object use, not sure why ..., but it should be a different patch. What I would like to see is making this security object optionally replicable (for clusters) but that's another point, another ticket. I'm not sure why do you mean when you say I got it wrong. Particularly offensive. What do you mean by query /testdb ? I think you misunderstood the patch. The alternative patch forbid anonymous users to query the db which is flagged as dropbox. Only admins car read it (readers can be added if there is a need to). Since anonymous users are forbidden they can't access to design docs so the views (a view imply to read the ddoc). _all_docs is a specific case. It shouldn't be part of couch_mrview in fact but like davisp said there isn't an easy way to separate it from it since we need to parse parameters and such. It will be part of another patch but I intend to propose a patch adding all_docs handling to couch_db module. But _all_docs is forbidden. About the count of db, what's the security issue here? If there is really an issue, a check could be added to dbinfo function too. But you should be aware that it will break then some couchdb clients. So here we have a working dropbox. There is no test for now, but this patch is actually used in a real project. Like I said I will add tests today. Also technically speaking this patch is really simple, it doesn't do much than allowing anonymous writes while preventing reading. Re security. My criticism are about security too. Testing on path and method is really awkward, it works "mostly" today, but what about the future?. When speaking about externals and other things I'm thinking to people that add plugins to couchdb. This expectation should be taken in consideration. While couchdb can't answers to all needs I see more and more people customizing it, adding plugins and such. We should support that by providing the right api imo. Also I don't want to force users to check that they handle correctly a dropbox feature etc which should be part of the core. That's the point of having it handled at lower level. I'm doing as much pluging as you do, and the more I work on that part, the more I think the couchdb core could simplify the life of these external coders. At a community point of view having more plugins developed is good.
        Hide
        Benoit Chesneau added a comment -

        @jason about

        """ No doubt, you are also sensitive to my frustration: I work hard to contribute to CouchDB, only to see (for the second time) a bigwig committer swoop down, make a quick critique, and post a half-hearted rewrite, showing no evidence of equivalent thoughtfulness and deliberation. """

        I put a comment previously here about what I was thinking, ie using couch_db:. This alternative patch implement it. It exists in refuge base code and is already used by some that's why I'm ***proposing** it. Posting a patch don't assure about the result. Also proposing alternative patch with different implementations are common in the opensource world.

        Show
        Benoit Chesneau added a comment - @jason about """ No doubt, you are also sensitive to my frustration: I work hard to contribute to CouchDB, only to see (for the second time) a bigwig committer swoop down, make a quick critique, and post a half-hearted rewrite, showing no evidence of equivalent thoughtfulness and deliberation. """ I put a comment previously here about what I was thinking, ie using couch_db: . This alternative patch implement it. It exists in refuge base code and is already used by some that's why I'm ***proposing ** it. Posting a patch don't assure about the result. Also proposing alternative patch with different implementations are common in the opensource world.
        Hide
        Jason Smith added a comment -

        Hi, Benoit. No offense intended: as I re-read your patch I think you and I are making different features under the same name. The following Bash script clarifies my critique. I think you will agree that either (a) we are working on different things, with a name collision, "dropbox"; or (b) your patch is careless and dangerous.

        #!/bin/bash

        1. Given: admin user "admin" and normal users "amy" and "bob"
        2. New database
          curl -X DELETE http://admin:admin@localhost:5984/db
          curl -X PUT http://admin:admin@localhost:5984/db
        1. Create a document
          curl -X PUT http://admin:admin@localhost:5984/db/doc1 -d ' {"hello":"world"}

          '
          curl -X PUT http://admin:admin@localhost:5984/db/doc2 -d '

          {"hello":"world"}

          '

        1. Amy is a member. Bob is not.
          curl -X PUT http://admin:admin@localhost:5984/db/_security -d '{"members":{"names":["amy"]}}'
        1. Amy can open /db
          curl --fail http://amy:amy@localhost:5984/db
        1. Bob cannot open /db
          curl --fail http://bob:bob@localhost:5984/db
        1. Make a dropbox db
          curl -X PUT http://admin:admin@localhost:5984/db/_security -d '
          Unknown macro: {"members"}

          '

        1. Member amy cannot get a doc (regression)
          curl --fail http://amy:amy@localhost:5984/db/doc1
        1. Non-member bob can get DB metadata (minor breach)
          curl --fail http://bob:bob@localhost:5984/db
        1. Member amy cannot get _all_docs (regression)
          curl --fail http://amy:amy@localhost:5984/db/_all_docs
        1. Non-member bob can fetch the entire database (major breach)
          curl --fail http://bob:bob@localhost:5984/db/_changes?include_docs=true
        1. Anonymous users can fetch the entire database (major breach)
          curl --fail http://localhost:5984/db/_changes?include_docs=true
        Show
        Jason Smith added a comment - Hi, Benoit. No offense intended: as I re-read your patch I think you and I are making different features under the same name. The following Bash script clarifies my critique. I think you will agree that either (a) we are working on different things, with a name collision, "dropbox"; or (b) your patch is careless and dangerous. #!/bin/bash Given: admin user "admin" and normal users "amy" and "bob" New database curl -X DELETE http://admin:admin@localhost:5984/db curl -X PUT http://admin:admin@localhost:5984/db Create a document curl -X PUT http://admin:admin@localhost:5984/db/doc1 -d ' {"hello":"world"} ' curl -X PUT http://admin:admin@localhost:5984/db/doc2 -d ' {"hello":"world"} ' Amy is a member. Bob is not. curl -X PUT http://admin:admin@localhost:5984/db/_security -d '{"members":{"names": ["amy"] }}' Amy can open /db curl --fail http://amy:amy@localhost:5984/db Bob cannot open /db curl --fail http://bob:bob@localhost:5984/db Make a dropbox db curl -X PUT http://admin:admin@localhost:5984/db/_security -d ' Unknown macro: {"members"} ' Member amy cannot get a doc (regression) curl --fail http://amy:amy@localhost:5984/db/doc1 Non-member bob can get DB metadata (minor breach) curl --fail http://bob:bob@localhost:5984/db Member amy cannot get _all_docs (regression) curl --fail http://amy:amy@localhost:5984/db/_all_docs Non-member bob can fetch the entire database (major breach) curl --fail http://bob:bob@localhost:5984/db/_changes?include_docs=true Anonymous users can fetch the entire database (major breach) curl --fail http://localhost:5984/db/_changes?include_docs=true
        Hide
        Benoit Chesneau added a comment -

        Ok i'm starting annoyed. To be clear I'm -1 about an implementation based on paths**. While authentication is done at HTTP level, authorization shouldn't. It should be resource or feature based. Basing auth on paths and methods open the door to a lot of unexpected problems imo. So I proposed an alternative patch to handle a dropbox features where goal is simple :

        • allows anyone to post a doc.
        • only db admins can read or query these docs.
        • a dropbox db looks empty for anyone except for admins.
        • be handled at the core level (couch_db or core functions) when possible to make it easier for the dev to handle these topics.

        Which is sensibly the same you described. I simplified maybe a little in attempt to make it easier to use and implement.

        re the alternative patch I posted . _changes is indeed displaying the docids, however this isn't true when you say it's insecure or dangerous. it doesn't display a doc content, it actually return null (see following tests...) and _all_docs return a 401 error . It is incomplete: _changes features like _all_docs should test if the user is an admin first. New patch is coming fixing that.

        /testdb return numbers of docs. Not sure why it's a breach here but I can understand the logic. I will again provide a patch fixing that.

        Tests:

        $ curl -XPUT http://admin:test@localhost:5984/testdb

        {"ok":true}

        $ curl -XPUT http://admin:test@localhost:5984/testdb/_security -d'

        {"dropbox": true}

        '

        {"ok":true}

        $ curl -XPOST http://localhost:5984/testdb -d'

        {"k": "v"}

        ' -H'Content-Type: application/json'

        {"ok":true,"id":"9cee7d60bc1a4e9dbc7584b3f6000f61","rev":"1-1be5a5c6039dc44fff8d7a6920129496"}

        $ curl -XGET http://localhost:5984/testdb/9cee7d60bc1a4e9dbc7584b3f6000f61

        {"error":"unauthorized","reason":"You are not a db or server admin."}

        $ curl -XGET http://test:test@localhost:5984/testdb/9cee7d60bc1a4e9dbc7584b3f6000f61

        {"error":"unauthorized","reason":"You are not a db or server admin."}

        $ curl -XGET http://localhost:5984/testdb/_all_docs

        {"error":"unauthorized","reason":"You are not a db or server admin."}

        $ curl -XGET http://localhost:5984/testdb/_all_docs -I
        HTTP/1.1 401 Unauthorized
        Server: CouchDB/1.3.0a-b4295e6-git (Erlang OTP/R14B04)
        Date: Mon, 21 Nov 2011 04:03:25 GMT
        Content-Type: text/plain; charset=utf-8
        Content-Length: 70

        $ curl -XGET http://admin:test@localhost:5984/testdb/_all_docs
        {"total_rows":1,"offset":0,"rows":[
        {"id":"9cee7d60bc1a4e9dbc7584b3f6000f61","key":"9cee7d60bc1a4e9dbc7584b3f6000f61","value":{"rev":"1-1be5a5c6039dc44fff8d7a6920129496"}}
        ]}

        $ curl -XGET http://localhost:5984/testdb/_changes
        {"results":[
        {"seq":2,"id":"9cee7d60bc1a4e9dbc7584b3f6000f61","changes":[

        {"rev":"1-1be5a5c6039dc44fff8d7a6920129496"}

        ]}
        ],
        "last_seq":2}

        Benoits-MacBook-Air:~ benoitc$ curl -XGET http://localhost:5984/testdb/_changes?include_docs=true
        {"results":[
        {"seq":2,"id":"9cee7d60bc1a4e9dbc7584b3f6000f61","changes":[

        {"rev":"1-1be5a5c6039dc44fff8d7a6920129496"}

        ],"doc":null}
        ],
        "last_seq":2}

        $ curl -XGET http://admin:test@localhost:5984/testdb/_changes?include_docs=true
        {"results":[
        {"seq":2,"id":"9cee7d60bc1a4e9dbc7584b3f6000f61","changes":[

        {"rev":"1-1be5a5c6039dc44fff8d7a6920129496"}

        ],"doc":{"_id":"9cee7d60bc1a4e9dbc7584b3f6000f61","_rev":"1-1be5a5c6039dc44fff8d7a6920129496","k":"v"}}
        ],
        "last_seq":2}

        Show
        Benoit Chesneau added a comment - Ok i'm starting annoyed. To be clear I'm -1 about an implementation based on paths**. While authentication is done at HTTP level, authorization shouldn't. It should be resource or feature based. Basing auth on paths and methods open the door to a lot of unexpected problems imo. So I proposed an alternative patch to handle a dropbox features where goal is simple : allows anyone to post a doc. only db admins can read or query these docs. a dropbox db looks empty for anyone except for admins. be handled at the core level (couch_db or core functions) when possible to make it easier for the dev to handle these topics. Which is sensibly the same you described. I simplified maybe a little in attempt to make it easier to use and implement. re the alternative patch I posted . _changes is indeed displaying the docids, however this isn't true when you say it's insecure or dangerous. it doesn't display a doc content, it actually return null (see following tests...) and _all_docs return a 401 error . It is incomplete: _changes features like _all_docs should test if the user is an admin first. New patch is coming fixing that. /testdb return numbers of docs. Not sure why it's a breach here but I can understand the logic. I will again provide a patch fixing that. Tests: $ curl -XPUT http://admin:test@localhost:5984/testdb {"ok":true} $ curl -XPUT http://admin:test@localhost:5984/testdb/_security -d' {"dropbox": true} ' {"ok":true} $ curl -XPOST http://localhost:5984/testdb -d' {"k": "v"} ' -H'Content-Type: application/json' {"ok":true,"id":"9cee7d60bc1a4e9dbc7584b3f6000f61","rev":"1-1be5a5c6039dc44fff8d7a6920129496"} $ curl -XGET http://localhost:5984/testdb/9cee7d60bc1a4e9dbc7584b3f6000f61 {"error":"unauthorized","reason":"You are not a db or server admin."} $ curl -XGET http://test:test@localhost:5984/testdb/9cee7d60bc1a4e9dbc7584b3f6000f61 {"error":"unauthorized","reason":"You are not a db or server admin."} $ curl -XGET http://localhost:5984/testdb/_all_docs {"error":"unauthorized","reason":"You are not a db or server admin."} $ curl -XGET http://localhost:5984/testdb/_all_docs -I HTTP/1.1 401 Unauthorized Server: CouchDB/1.3.0a-b4295e6-git (Erlang OTP/R14B04) Date: Mon, 21 Nov 2011 04:03:25 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 70 $ curl -XGET http://admin:test@localhost:5984/testdb/_all_docs {"total_rows":1,"offset":0,"rows":[ {"id":"9cee7d60bc1a4e9dbc7584b3f6000f61","key":"9cee7d60bc1a4e9dbc7584b3f6000f61","value":{"rev":"1-1be5a5c6039dc44fff8d7a6920129496"}} ]} $ curl -XGET http://localhost:5984/testdb/_changes {"results":[ {"seq":2,"id":"9cee7d60bc1a4e9dbc7584b3f6000f61","changes":[ {"rev":"1-1be5a5c6039dc44fff8d7a6920129496"} ]} ], "last_seq":2} Benoits-MacBook-Air:~ benoitc$ curl -XGET http://localhost:5984/testdb/_changes?include_docs=true {"results":[ {"seq":2,"id":"9cee7d60bc1a4e9dbc7584b3f6000f61","changes":[ {"rev":"1-1be5a5c6039dc44fff8d7a6920129496"} ],"doc":null} ], "last_seq":2} $ curl -XGET http://admin:test@localhost:5984/testdb/_changes?include_docs=true {"results":[ {"seq":2,"id":"9cee7d60bc1a4e9dbc7584b3f6000f61","changes":[ {"rev":"1-1be5a5c6039dc44fff8d7a6920129496"} ],"doc":{"_id":"9cee7d60bc1a4e9dbc7584b3f6000f61","_rev":"1-1be5a5c6039dc44fff8d7a6920129496","k":"v"}} ], "last_seq":2}
        Hide
        Randall Leeds added a comment -

        I'm pretty sure you two won't actually hold a grudge, but try to be more civil. I'd really rather outside observers not think we all hate each other in this community.

        I've been super busy lately, or I'd offer a complete review myself. It sounds like you're close to reconciling your expectations, though, and that you may both be writing to the same feature. I agree with the approach of Benoit's patch more, though, re: the level at which authorisation is controlled.

        Benoit, can you put it on a branch along with Jason's tests? I think if you can get your patch to pass his tests we'll be a lot closer to landing this.

        Show
        Randall Leeds added a comment - I'm pretty sure you two won't actually hold a grudge, but try to be more civil. I'd really rather outside observers not think we all hate each other in this community. I've been super busy lately, or I'd offer a complete review myself. It sounds like you're close to reconciling your expectations, though, and that you may both be writing to the same feature. I agree with the approach of Benoit's patch more, though, re: the level at which authorisation is controlled. Benoit, can you put it on a branch along with Jason's tests? I think if you can get your patch to pass his tests we'll be a lot closer to landing this.
        Hide
        Benoit Chesneau added a comment -

        patch fixing _changes handling. It now return a 401 error when your not allowed to access it :

        $ curl -XGET http://localhost:5984/testdb/_changes

        {"error":"unauthorized","reason":"You are not a db or server admin."}

        $ curl -XGET http://admin:test@localhost:5984/testdb/_changes?include_docs=true
        {"results":[
        {"seq":2,"id":"9cee7d60bc1a4e9dbc7584b3f6000f61","changes":[

        {"rev":"1-1be5a5c6039dc44fff8d7a6920129496"}

        ],"doc":{"_id":"9cee7d60bc1a4e9dbc7584b3f6000f61","_rev":"1-1be5a5c6039dc44fff8d7a6920129496","k":"v"}}
        ],
        "last_seq":2}

        another patch is coming to solve db_info

        Show
        Benoit Chesneau added a comment - patch fixing _changes handling. It now return a 401 error when your not allowed to access it : $ curl -XGET http://localhost:5984/testdb/_changes {"error":"unauthorized","reason":"You are not a db or server admin."} $ curl -XGET http://admin:test@localhost:5984/testdb/_changes?include_docs=true {"results":[ {"seq":2,"id":"9cee7d60bc1a4e9dbc7584b3f6000f61","changes":[ {"rev":"1-1be5a5c6039dc44fff8d7a6920129496"} ],"doc":{"_id":"9cee7d60bc1a4e9dbc7584b3f6000f61","_rev":"1-1be5a5c6039dc44fff8d7a6920129496","k":"v"}} ], "last_seq":2} another patch is coming to solve db_info
        Hide
        Benoit Chesneau added a comment -

        @randall sure, that was my intention. I will do in the morning (on it right now) .

        @jason I will aslo fix the issues you raised

        Show
        Benoit Chesneau added a comment - @randall sure, that was my intention. I will do in the morning (on it right now) . @jason I will aslo fix the issues you raised
        Hide
        Jason Smith added a comment -

        I hope outside observers would see a spirited debate, neither nasty nor personal.

        Benoit, I have no -1 veto power. However I hope to hear a response to my critique: special-case "dropbox" handling must be sprinkled all over the code base. We cannot prove that this feature is 100% secure; we can only make as many unit tests as possible, to be reasonably confident.

        Authorization should not be decided at the HTTP level; however, in the current code base, that is the only choke-point. Once you couch_db:open(), there are two problems:

        1. Read and write access is unrestricted
        2. Subsequent code has lost the Req object, so there is no context to decide yes/no

        Show
        Jason Smith added a comment - I hope outside observers would see a spirited debate, neither nasty nor personal. Benoit, I have no -1 veto power. However I hope to hear a response to my critique: special-case "dropbox" handling must be sprinkled all over the code base. We cannot prove that this feature is 100% secure; we can only make as many unit tests as possible, to be reasonably confident. Authorization should not be decided at the HTTP level; however, in the current code base, that is the only choke-point. Once you couch_db:open(), there are two problems: 1. Read and write access is unrestricted 2. Subsequent code has lost the Req object, so there is no context to decide yes/no
        Hide
        Jason Smith added a comment -

        When writing the patch, I had in mind the next feature, with a very similar implementation.

        I want to implement an execute-only database. Non-members may not do anything except _show, _list, and _update. Thus, Couch app developers would have complete per-document authorization control. Execute-only can also support a reference implementation of Chris's _acl idea.

        I hope that, whatever implementation sticks, it can blaze the trail for similar exceptions to the traditional _security requirements.

        Show
        Jason Smith added a comment - When writing the patch, I had in mind the next feature, with a very similar implementation. I want to implement an execute-only database. Non-members may not do anything except _show, _list, and _update. Thus, Couch app developers would have complete per-document authorization control. Execute-only can also support a reference implementation of Chris's _acl idea. I hope that, whatever implementation sticks, it can blaze the trail for similar exceptions to the traditional _security requirements.
        Hide
        Benoit Chesneau added a comment -

        fake db infos when dropbox=true and the user isn't authorized. This patch is done on top of 0001-handle-dropbox-db.-Add-dropbox-true-to-security-obje.patch

        All sizes and counts informations are set to 0 so an unauthorized user view the db as empty. Should fix last issue raised by @jason about the db_info minor security.

        $ curl -XGET http://localhost:5984/testdb

        {"db_name":"testdb","doc_count":0,"doc_del_count":0,"update_seq":0,"purge_seq":0,"compact_running":false,"disk_size":0,"data_size":0,"instance_start_time":"1321948511448569","disk_format_version":6,"committed_update_seq":0}

        $ curl -XGET http://admin:test@localhost:5984/testdb

        {"db_name":"testdb","doc_count":1,"doc_del_count":0,"update_seq":2,"purge_seq":0,"compact_running":false,"disk_size":8283,"data_size":279,"instance_start_time":"1321948511448569","disk_format_version":6,"committed_update_seq":2}
        Show
        Benoit Chesneau added a comment - fake db infos when dropbox=true and the user isn't authorized. This patch is done on top of 0001-handle-dropbox-db.-Add-dropbox-true-to-security-obje.patch All sizes and counts informations are set to 0 so an unauthorized user view the db as empty. Should fix last issue raised by @jason about the db_info minor security. $ curl -XGET http://localhost:5984/testdb {"db_name":"testdb","doc_count":0,"doc_del_count":0,"update_seq":0,"purge_seq":0,"compact_running":false,"disk_size":0,"data_size":0,"instance_start_time":"1321948511448569","disk_format_version":6,"committed_update_seq":0} $ curl -XGET http://admin:test@localhost:5984/testdb {"db_name":"testdb","doc_count":1,"doc_del_count":0,"update_seq":2,"purge_seq":0,"compact_running":false,"disk_size":8283,"data_size":279,"instance_start_time":"1321948511448569","disk_format_version":6,"committed_update_seq":2}
        Hide
        Jason Smith added a comment -
        • If user is not a member, normally: GET /db -> 401 Unauthorized
        • If user is not a member, dropbox: GET /db -> 200 OK, faux data

        Is that the idea? Thanks.

        Show
        Jason Smith added a comment - If user is not a member, normally: GET /db -> 401 Unauthorized If user is not a member, dropbox: GET /db -> 200 OK, faux data Is that the idea? Thanks.
        Hide
        Benoit Chesneau added a comment - - edited

        no?

        if user is not a member and db is flagged as dropbox : /GET db => appear as empty
        if use is admin and db is flagged as dropbox -> /GET db i=> return real db information

        Note for now only admins can read a dropbox db. But if it's really needed and wanted
        we could add readers too. Thoughts?

        Show
        Benoit Chesneau added a comment - - edited no? if user is not a member and db is flagged as dropbox : /GET db => appear as empty if use is admin and db is flagged as dropbox -> /GET db i=> return real db information Note for now only admins can read a dropbox db. But if it's really needed and wanted we could add readers too. Thoughts?
        Hide
        Jason Smith added a comment -

        I see. You return 200 OK for a non-member query to /db.

        My feeling is that admin-only access to a dropbox db is not useful. That is why my number 1 requirement is that everything stays the same as before and that is confirmed in my test suite.

        Show
        Jason Smith added a comment - I see. You return 200 OK for a non-member query to /db. My feeling is that admin-only access to a dropbox db is not useful. That is why my number 1 requirement is that everything stays the same as before and that is confirmed in my test suite.
        Hide
        Benoit Chesneau added a comment -

        i return 200 but with a different message. That's expected since you really want to say it's OK to use this resource.

        I don't understand the second part. What is it supposed to mean? What is the action you would like to be done?

        Show
        Benoit Chesneau added a comment - i return 200 but with a different message. That's expected since you really want to say it's OK to use this resource. I don't understand the second part. What is it supposed to mean? What is the action you would like to be done?
        Hide
        Tyler Johnson added a comment -

        Hey folks. Just wondering whatever happened with this. Looks like it was well on track.

        Show
        Tyler Johnson added a comment - Hey folks. Just wondering whatever happened with this. Looks like it was well on track.
        Hide
        Paul Frazee added a comment -

        Is this feature still on track for merging? If not, is there an alternative that doesn't require a 2.1-tier?

        Show
        Paul Frazee added a comment - Is this feature still on track for merging? If not, is there an alternative that doesn't require a 2.1-tier?
        Hide
        Klaus Trainer added a comment - - edited

        As I was recently in need of this feature, I rebased Benoit's current
        version of the patch and had a look at it. The patch looks simple and
        straight-forward. It checks authorization based on the user context in
        the #db record, and it simply differentiates between admins and non-
        admins.

        So, with Benoit's implementation it is possible to send "private
        messages" as anonymous (i.e. unauthenticated) or authenticated non-
        admin user to an admin, but it is not possible to send one to someone
        who is not an admin. In short, the receiver always has to be an admin.

        Although Jason originally proposed a solution that wouldn't require a
        receiver to be an admin, I'd propose to keep that constraint for the
        following reasons:

        • it's less complex from an implementation perspective, i.e., the
          changes that need to be done are more straight-forward and less
          intrusive
        • it's less complex from a user perspective.

        Here's my list of things that should definitely be done in order to get
        this feature ready for a future release (please tell me if you think
        something is missing here):

        • clarify naming (inbox, dropbox, allow_anonymous_writes, write_only)
        • add tests
        • add documentation
        • reflect the feature in Fa?ux?ton; for instance, add a checkbox in the
          respective "Security" menu.
        Show
        Klaus Trainer added a comment - - edited As I was recently in need of this feature, I rebased Benoit's current version of the patch and had a look at it. The patch looks simple and straight-forward. It checks authorization based on the user context in the #db record, and it simply differentiates between admins and non- admins. So, with Benoit's implementation it is possible to send "private messages" as anonymous (i.e. unauthenticated) or authenticated non- admin user to an admin, but it is not possible to send one to someone who is not an admin. In short, the receiver always has to be an admin. Although Jason originally proposed a solution that wouldn't require a receiver to be an admin, I'd propose to keep that constraint for the following reasons: it's less complex from an implementation perspective, i.e., the changes that need to be done are more straight-forward and less intrusive it's less complex from a user perspective. Here's my list of things that should definitely be done in order to get this feature ready for a future release (please tell me if you think something is missing here): clarify naming (inbox, dropbox, allow_anonymous_writes, write_only) add tests add documentation reflect the feature in Fa?ux?ton; for instance, add a checkbox in the respective "Security" menu.
        Hide
        Kevin Gaudin added a comment -

        Hi,

        I would really love this feature to be available too.
        My main concern is that the current documentation let me think that this was already possible:

        If both the names and roles fields of either the admins or members properties are empty arrays, it means the database has no admins or members. Having no admins, only server admins (with the reserved _admin role) are able to update design document and make other admin level changes. Having no members, any user can write regular documents (any non-design document) and read documents from the database.

        Note: If there are any member names or roles defined for a database, then only authenticated users having a matching name or role are allowed to read documents from the database (or do a GET /db_name/ call).

        From the Wiki

        The first paragraph states that 'Having no members, any user can WRITE [...] and READ', then the note explains that with members set 'only authenticated users [...] are allowed to READ'. What about WRITE?

        I am a newcomer in the CouchDB community and as a fresh CouchApp developer (Acralyzer), the security model of CouchDB is what has been puzzling me the most (and I knew nothing about document based databases and MapReduce).

        If this "write-only" mode ever comes integrated in CouchDB, please make it something simple to understand:

        • A "dropbox" flag that would instantly prevent members to read from a DB is not simple to understand.
        • If I'm not allowed to read some data, I'm supposed to get a 401 error and not an empty or null 200 OK.

        I really liked in this thread Jason Smith's idea of a _security.readers and _security.writers roles definition. The idea of an execute-only database is interesting too to allow some users to access only to the higher levels of the database and not its internals.

        I'm loving CouchDB so far but its fuzzy access policy sometimes makes me regret this choice for Acralyzer. Reading today that you were so close to an agreement a year ago is both encouraging (it might come someday!) and disappointing (none of both proposed implementations got merged after 1 year).

        Come on guys, I'm sure you can find a great solution!

        Show
        Kevin Gaudin added a comment - Hi, I would really love this feature to be available too. My main concern is that the current documentation let me think that this was already possible: If both the names and roles fields of either the admins or members properties are empty arrays, it means the database has no admins or members. Having no admins, only server admins (with the reserved _admin role) are able to update design document and make other admin level changes. Having no members, any user can write regular documents (any non-design document) and read documents from the database. Note: If there are any member names or roles defined for a database, then only authenticated users having a matching name or role are allowed to read documents from the database (or do a GET /db_name/ call). From the Wiki The first paragraph states that 'Having no members, any user can WRITE [...] and READ', then the note explains that with members set 'only authenticated users [...] are allowed to READ'. What about WRITE? I am a newcomer in the CouchDB community and as a fresh CouchApp developer ( Acralyzer ), the security model of CouchDB is what has been puzzling me the most (and I knew nothing about document based databases and MapReduce). If this "write-only" mode ever comes integrated in CouchDB, please make it something simple to understand: A "dropbox" flag that would instantly prevent members to read from a DB is not simple to understand. If I'm not allowed to read some data, I'm supposed to get a 401 error and not an empty or null 200 OK. I really liked in this thread Jason Smith 's idea of a _security.readers and _security.writers roles definition. The idea of an execute-only database is interesting too to allow some users to access only to the higher levels of the database and not its internals. I'm loving CouchDB so far but its fuzzy access policy sometimes makes me regret this choice for Acralyzer. Reading today that you were so close to an agreement a year ago is both encouraging (it might come someday!) and disappointing (none of both proposed implementations got merged after 1 year). Come on guys, I'm sure you can find a great solution!
        Hide
        Kevin Gaudin added a comment -

        I just figured out that Cloudant have their own security system with a specific _writer role.

        This is exactly what I needed.

        I really would love to see this as a standard CouchDB feature.

        Show
        Kevin Gaudin added a comment - I just figured out that Cloudant have their own security system with a specific _writer role. This is exactly what I needed. I really would love to see this as a standard CouchDB feature.
        Show
        Benoit Chesneau added a comment - Kevin Gaudin https://github.com/refuge/couch_core/commit/742846156eb5b881f88b88c6deecbef4e66ed2a0 does that somehow.
        Hide
        Dave Cottlehuber added a comment -

        Klaus Trainer Benoit Chesneau where are we at for this?

        Show
        Dave Cottlehuber added a comment - Klaus Trainer Benoit Chesneau where are we at for this?
        Hide
        Benoit Chesneau added a comment -

        Dave Cottlehuberwelll would this patch be OK?

        Show
        Benoit Chesneau added a comment - Dave Cottlehuber welll would this patch be OK?
        Hide
        Klaus Trainer added a comment -

        @Dave Cottlehuber: Although I like Benoit's implementation and feel confident about its correctness and usefulness (see my earlier comment), it's not what Jason proposed here. Note Jason's concern he raised: "My feeling is that admin-only access to a dropbox db is not useful."

        As I don't agree with Jason here, and think that admin-only read access would definitely be useful, I'd rather like to ask in which regard admin-only read access were less useful than compared to having read access for admins and members.

        In Jason's implementation all members have the same read access rights for all documents. Whereas, in Benoit's implementation only admins have read access rights, and members don't have any additional authorization than compared to anonymous users. Note that with both implementations it would be possible to add an execute-only authorization (like a UNIX directory permission with only the executable bit set) feature, where members are able to read-access a document if they retrieve it by its id, but not otherwise.

        Show
        Klaus Trainer added a comment - @ Dave Cottlehuber : Although I like Benoit's implementation and feel confident about its correctness and usefulness (see my earlier comment), it's not what Jason proposed here. Note Jason's concern he raised: "My feeling is that admin-only access to a dropbox db is not useful." As I don't agree with Jason here, and think that admin-only read access would definitely be useful, I'd rather like to ask in which regard admin-only read access were less useful than compared to having read access for admins and members. In Jason's implementation all members have the same read access rights for all documents. Whereas, in Benoit's implementation only admins have read access rights, and members don't have any additional authorization than compared to anonymous users. Note that with both implementations it would be possible to add an execute-only authorization (like a UNIX directory permission with only the executable bit set) feature, where members are able to read-access a document if they retrieve it by its id, but not otherwise.

          People

          • Assignee:
            Unassigned
            Reporter:
            Jason Smith
          • Votes:
            9 Vote for this issue
            Watchers:
            11 Start watching this issue

            Dates

            • Created:
              Updated:

              Development