You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@couchdb.apache.org by Damien Katz <da...@apache.org> on 2008/11/21 23:12:51 UTC

New Security and Validation Features

Here is brief outline of the new security and validation stuff.

-Authentication, batteries not included-

Currently CouchDB contains no general authentication modules, but does  
allow for plug-in authentication modules via setting in the ini.

The test suite uses a special test authentication module, with  
hardcoded names and passwords and simple protocol with everything sent  
cleartext. It can serve as an example and starting point for building  
real authentication modules, like modules that connect to external  
LDAP or Active Directory servers.

Eventually we'll include a built-in authentication module that uses an  
internal CouchDB database for user accounts.

The authentication module, upon successful authentication, returns a  
user context object that has the user's name and list of roles, and  
perhaps more meta information about the user. This context object is  
then later used in validation of updates of both design and regular  
documents.

The list of roles for a user would be something like ["Engineer",  
"Party Planning Committee", "Discussion Moderator"].

-Server and DB Admins-

If the authentication module gives the user the role of "_admin", they  
are given server wide admin access. Server admins can create and  
delete databases, and set the individual DB admins and update design  
documents. (By default, until admin accounts are turned, all users are  
admins)

Each database has an DB Admins list. It's a simple list of user names  
and roles that are allow administrator access to the database. If a  
user's name or a role appear in the DB Admins list, then that user is  
a DB Admin. The DB Admins, along with Server Admins, are allowed to  
change the DB Admins list, to add or remove admin access for others,  
or remove admin access for themselves. Server Admins are automatically  
DB Admins. Also, design documents can only be created/updated by admins.

The admin list  be should relatively small, it's kept in memory.

I'm thinking the ability to create temp view should be restricted to  
admins as well, or at least configurable as such. Currently anyone can  
make temp view queries.

-Authorization/Validation-

Each design document can contain a document update validation  
function. Like views, these can be in any language. The language is  
set at the design document level.

On document update -- either via interactive update or via replication  
-- each is run in succession. These validation functions are  
responsible for enforcing document constraints or schemas, and to  
enforce security.

Validation functions are provided the new document, previous revision  
of the document on disk, and the user context. The user context has  
the users name and roles.

If the document values don't pass validation, a forbidden exception is  
returned If the user isn't allow to update the document, a  
unauthorized exception is returned.

This scheme can be used for signature based security (is the update  
signed by an authorized user) or user based security (is the user  
currently writing the update an authorized user).

This user based example ensures that every document has an authors  
field and when updating an existing document, you are an allowed  
author, or a moderator:

function(newDocument, previousDocument, userCtx) {
   if (!newDocument._deleted && !newDocument.author) {
	throw {forbidden, "All documents must have an author specified."}
   }
   if (previousDocument &&
	previousDocument.author != userCtx.name &&
	userCtx.roles.indexOf("Discussion Moderator") == -1) {
  	throw {unauthorized, "You are not the author of this document."}
   }
}

The validation works with replication too, all updates, whether  
interactive or replicated are validated. But the replication still  
needs testing and might be buggy on update failures.

That's all for now. Question and comments please.

  -Damien



Re: New Security and Validation Features

Posted by Chris Anderson <jc...@gmail.com>.

On Nov 21, 2008, at 9:18 PM, Noah Slater <ns...@apache.org> wrote:

> That's what she said! :/

/groan

Q for Damien: could the validation function take care of adding the  
author from the user context for new documents, or must it refrain  
from changing the incoming document?

I'm a little unclear about how the user context for replication will  
appear. It will be the user who triggered the replication? Or a user  
corresponding to the source database? Will there be a way for  
validation functions to know when the update comes via replication as  
opposed to from a regular update?

Chris

>
>
> On Fri, Nov 21, 2008 at 06:52:43PM -0800, Bradford Winfrey wrote:
>> isn't that a full,colon?
>>
>> (add joke here)
>>
>>
>>
>>
>> ________________________________
>> From: Damien Katz <da...@apache.org>
>> To: couchdb-dev@incubator.apache.org
>> Sent: Friday, November 21, 2008 6:17:03 PM
>> Subject: Re: New Security and Validation Features
>>
>> The correct one has a semi-colon after forbidden.
>>
>> On Nov 21, 2008, at 7:10 PM, Noah Slater wrote:
>>
>>> On Fri, Nov 21, 2008 at 05:42:39PM -0500, Damien Katz wrote:
>>>>>  throw {forbidden, "All documents must have an author specified."}
>>>
>>>>   throw {forbidden: "All documents must have an author specified."}
>>>
>>> These are the same?
>>>
>>
>>
>>
> -- 
> Noah Slater, http://tumbolia.org/nslater

Re: New Security and Validation Features

Posted by Noah Slater <ns...@apache.org>.
That's what she said! :/

On Fri, Nov 21, 2008 at 06:52:43PM -0800, Bradford Winfrey wrote:
> isn't that a full,colon?
>
> (add joke here)
>
>
>
>
> ________________________________
> From: Damien Katz <da...@apache.org>
> To: couchdb-dev@incubator.apache.org
> Sent: Friday, November 21, 2008 6:17:03 PM
> Subject: Re: New Security and Validation Features
>
> The correct one has a semi-colon after forbidden.
>
> On Nov 21, 2008, at 7:10 PM, Noah Slater wrote:
>
> > On Fri, Nov 21, 2008 at 05:42:39PM -0500, Damien Katz wrote:
> >>>   throw {forbidden, "All documents must have an author specified."}
> >
> >>    throw {forbidden: "All documents must have an author specified."}
> >
> > These are the same?
> >
>
>
>
-- 
Noah Slater, http://tumbolia.org/nslater

Re: New Security and Validation Features

Posted by Damien Katz <da...@apache.org>.
Oops, yeah, full colon.

-Damien

On Nov 21, 2008, at 9:52 PM, Bradford Winfrey wrote:

> isn't that a full,colon?
>
> (add joke here)
>
>
>
>
> ________________________________
> From: Damien Katz <da...@apache.org>
> To: couchdb-dev@incubator.apache.org
> Sent: Friday, November 21, 2008 6:17:03 PM
> Subject: Re: New Security and Validation Features
>
> The correct one has a semi-colon after forbidden.
>
> On Nov 21, 2008, at 7:10 PM, Noah Slater wrote:
>
>> On Fri, Nov 21, 2008 at 05:42:39PM -0500, Damien Katz wrote:
>>>>  throw {forbidden, "All documents must have an author specified."}
>>
>>>   throw {forbidden: "All documents must have an author specified."}
>>
>> These are the same?
>>
>> -- 
>> Noah Slater, http://tumbolia.org/nslater
>
>


Re: New Security and Validation Features

Posted by Bradford Winfrey <br...@yahoo.com>.
isn't that a full,colon?

(add joke here)




________________________________
From: Damien Katz <da...@apache.org>
To: couchdb-dev@incubator.apache.org
Sent: Friday, November 21, 2008 6:17:03 PM
Subject: Re: New Security and Validation Features

The correct one has a semi-colon after forbidden.

On Nov 21, 2008, at 7:10 PM, Noah Slater wrote:

> On Fri, Nov 21, 2008 at 05:42:39PM -0500, Damien Katz wrote:
>>>   throw {forbidden, "All documents must have an author specified."}
>
>>    throw {forbidden: "All documents must have an author specified."}
>
> These are the same?
>
> -- 
> Noah Slater, http://tumbolia.org/nslater


      

Re: New Security and Validation Features

Posted by Damien Katz <da...@apache.org>.
The correct one has a semi-colon after forbidden.

On Nov 21, 2008, at 7:10 PM, Noah Slater wrote:

> On Fri, Nov 21, 2008 at 05:42:39PM -0500, Damien Katz wrote:
>>>   throw {forbidden, "All documents must have an author specified."}
>
>>    throw {forbidden: "All documents must have an author specified."}
>
> These are the same?
>
> -- 
> Noah Slater, http://tumbolia.org/nslater


Re: New Security and Validation Features

Posted by Noah Slater <ns...@apache.org>.
On Fri, Nov 21, 2008 at 05:42:39PM -0500, Damien Katz wrote:
>>    throw {forbidden, "All documents must have an author specified."}

>     throw {forbidden: "All documents must have an author specified."}

These are the same?

-- 
Noah Slater, http://tumbolia.org/nslater

Re: New Security and Validation Features

Posted by Damien Katz <da...@apache.org>.
On Nov 21, 2008, at 5:34 PM, Dean Landolt wrote:
> Beautiful. And dead simple.
>
> I just have one question. What's this about:
>
>    throw {forbidden, "All documents must have an author specified."}
>
> Is that right? Is that an Erlangism intertwingled with javascript?

Hmm, that should have been:
throw {forbidden: "All documents must have an author specified."}

Re: New Security and Validation Features

Posted by Dean Landolt <de...@deanlandolt.com>.
On Fri, Nov 21, 2008 at 5:12 PM, Damien Katz <da...@apache.org> wrote:

> Here is brief outline of the new security and validation stuff.
>
> -Authentication, batteries not included-
>
> Currently CouchDB contains no general authentication modules, but does
> allow for plug-in authentication modules via setting in the ini.
>
> The test suite uses a special test authentication module, with hardcoded
> names and passwords and simple protocol with everything sent cleartext. It
> can serve as an example and starting point for building real authentication
> modules, like modules that connect to external LDAP or Active Directory
> servers.
>
> Eventually we'll include a built-in authentication module that uses an
> internal CouchDB database for user accounts.
>
> The authentication module, upon successful authentication, returns a user
> context object that has the user's name and list of roles, and perhaps more
> meta information about the user. This context object is then later used in
> validation of updates of both design and regular documents.
>
> The list of roles for a user would be something like ["Engineer", "Party
> Planning Committee", "Discussion Moderator"].
>
> -Server and DB Admins-
>
> If the authentication module gives the user the role of "_admin", they are
> given server wide admin access. Server admins can create and delete
> databases, and set the individual DB admins and update design documents. (By
> default, until admin accounts are turned, all users are admins)
>
> Each database has an DB Admins list. It's a simple list of user names and
> roles that are allow administrator access to the database. If a user's name
> or a role appear in the DB Admins list, then that user is a DB Admin. The DB
> Admins, along with Server Admins, are allowed to change the DB Admins list,
> to add or remove admin access for others, or remove admin access for
> themselves. Server Admins are automatically DB Admins. Also, design
> documents can only be created/updated by admins.
>
> The admin list  be should relatively small, it's kept in memory.
>
> I'm thinking the ability to create temp view should be restricted to admins
> as well, or at least configurable as such. Currently anyone can make temp
> view queries.
>
> -Authorization/Validation-
>
> Each design document can contain a document update validation function.
> Like views, these can be in any language. The language is set at the design
> document level.
>
> On document update -- either via interactive update or via replication --
> each is run in succession. These validation functions are responsible for
> enforcing document constraints or schemas, and to enforce security.
>
> Validation functions are provided the new document, previous revision of
> the document on disk, and the user context. The user context has the users
> name and roles.
>
> If the document values don't pass validation, a forbidden exception is
> returned If the user isn't allow to update the document, a unauthorized
> exception is returned.
>
> This scheme can be used for signature based security (is the update signed
> by an authorized user) or user based security (is the user currently writing
> the update an authorized user).
>
> This user based example ensures that every document has an authors field
> and when updating an existing document, you are an allowed author, or a
> moderator:
>
> function(newDocument, previousDocument, userCtx) {
>  if (!newDocument._deleted && !newDocument.author) {
>        throw {forbidden, "All documents must have an author specified."}
>  }
>  if (previousDocument &&
>        previousDocument.author != userCtx.name &&
>        userCtx.roles.indexOf("Discussion Moderator") == -1) {
>        throw {unauthorized, "You are not the author of this document."}
>  }
> }
>
> The validation works with replication too, all updates, whether interactive
> or replicated are validated. But the replication still needs testing and
> might be buggy on update failures.
>
> That's all for now. Question and comments please.
>
>  -Damien



Beautiful. And dead simple.

I just have one question. What's this about:

    throw {forbidden, "All documents must have an author specified."}

Is that right? Is that an Erlangism intertwingled with javascript?

Re: New Security and Validation Features

Posted by Adam Kocoloski <ad...@gmail.com>.
On Dec 3, 2008, at 8:01 PM, Chris Anderson wrote:

> On Wed, Dec 3, 2008 at 10:55 AM, Adam Kocoloski
> <ad...@gmail.com> wrote:
>>
>> Hi Damien, cool stuff.  Could we have it so that the user context  
>> passed to
>> the validation function includes a role of "_admin" if the user's  
>> name is in
>> the DB admins list?
>
> Why not just go all the way and include the full list of the user's  
> roles?

Hi Chris, that's the goal.  All the other roles are already being  
included in the context passed to the validation function.  DB admin  
is a bit of a special case since its a calculated quantity --  
specifically, a user is a DBA if there's a non-zero intersection  
between [#user_ctx.name | #user_ctx.roles] and #db.admins.

In the patch I appended _admin to the list of roles.  I didn't replace  
the existing ones.  Best,

Adam

Re: New Security and Validation Features

Posted by Chris Anderson <jc...@apache.org>.
On Wed, Dec 3, 2008 at 10:55 AM, Adam Kocoloski
<ad...@gmail.com> wrote:
>
> Hi Damien, cool stuff.  Could we have it so that the user context passed to
> the validation function includes a role of "_admin" if the user's name is in
> the DB admins list?

Why not just go all the way and include the full list of the user's roles?

-- 
Chris Anderson
http://jchris.mfdz.com

Re: New Security and Validation Features

Posted by Adam Kocoloski <ad...@gmail.com>.
On Nov 21, 2008, at 5:12 PM, Damien Katz wrote:

> -Authorization/Validation-
>
> Each design document can contain a document update validation  
> function. Like views, these can be in any language. The language is  
> set at the design document level.
>
> On document update -- either via interactive update or via  
> replication -- each is run in succession. These validation functions  
> are responsible for enforcing document constraints or schemas, and  
> to enforce security.
>
> Validation functions are provided the new document, previous  
> revision of the document on disk, and the user context. The user  
> context has the users name and roles.
>
> If the document values don't pass validation, a forbidden exception  
> is returned If the user isn't allow to update the document, a  
> unauthorized exception is returned.
>
> This scheme can be used for signature based security (is the update  
> signed by an authorized user) or user based security (is the user  
> currently writing the update an authorized user).
>
> This user based example ensures that every document has an authors  
> field and when updating an existing document, you are an allowed  
> author, or a moderator:
>
> function(newDocument, previousDocument, userCtx) {
>  if (!newDocument._deleted && !newDocument.author) {
> 	throw {forbidden, "All documents must have an author specified."}
>  }
>  if (previousDocument &&
> 	previousDocument.author != userCtx.name &&
> 	userCtx.roles.indexOf("Discussion Moderator") == -1) {
> 	throw {unauthorized, "You are not the author of this document."}
>  }
> }
>
> The validation works with replication too, all updates, whether  
> interactive or replicated are validated. But the replication still  
> needs testing and might be buggy on update failures.
>
> That's all for now. Question and comments please.
>
> -Damien

Hi Damien, cool stuff.  Could we have it so that the user context  
passed to the validation function includes a role of "_admin" if the  
user's name is in the DB admins list?  Maybe something as simple as

diff --git a/trunk/src/couchdb/couch_db.erl b/trunk/src/couchdb/ 
couch_db.erl
index 7de5b8d..4eed8bc 100644
--- a/trunk/src/couchdb/couch_db.erl
+++ b/trunk/src/couchdb/couch_db.erl
@@ -231,9 +231,14 @@ validate_doc_update(_Db, #doc{id= <<"_local/",_/ 
binary>>}=Doc, _GetDiskDocFun) -
      Doc;
  validate_doc_update(#db{name=DbName,user_ctx=Ctx}=Db, Doc,  
GetDiskDocFun) ->
      DiskDoc = GetDiskDocFun(),
+    UserName = Ctx#user_ctx.name,
+    Roles = Ctx#user_ctx.roles ++ case lists:member(UserName,  
Db#db.admins) of
+        true -> [<<"_admin">>];
+        false -> []
+    end,
      JsonCtx =  {[{<<"db">>, DbName},
-            {<<"name">>,Ctx#user_ctx.name},
-            {<<"roles">>,Ctx#user_ctx.roles}]},
+            {<<"name">>,UserName},
+            {<<"roles">>,Roles}]},
      [case Fun(Doc, DiskDoc, JsonCtx) of
          ok -> ok;
          Error -> throw(Error)

Best, Adam