You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@couchdb.apache.org by Matt Goodall <ma...@gmail.com> on 2010/01/09 16:34:51 UTC

Initial couchdb accounts feedback

Hi,

Just a quick bit of feedback after an initial play with the new accounts
stuff. Definitely looks interesting! This is based on a fresh install from
trunk (r896989).

Oh, I should point out that I've never used couchdb to host any sort of
couchapp yet (I use couchdb as a "conventional" store) so I may well be
missing the point in a few places.


= Bugs =

If the 'users' database doesn't exist then the doc for the first admin user
(the one who spoils the party) does not get created.

Anyone can delete users' docs (even an admin user's doc). _admin users
should be able to delete docs. Unauthenticated users should not. I can't
decide if a user should be able to delete their own doc.


= Possible Simple Changes =

Perhaps the database could be renamed to "_users" as it's a couchdb-managed
database? I imagine it's reasonably likely there are databases called
"users" in use already.

The _admin/users view emits the whole doc. Would it make sense to use
include_docs=true where necessary and save the map's emitted value for
something useful in the future?

Perhaps store admin users in the "users" database with a role of "_admin",
and leave local.ini alone? I guess there are some
backward-compatibility issues to resolve here.


= Other Thoughts =

Is the "users" database designed to be replicated? If so, isn't there a real
danger of getting a username conflict and exposing another user's personal
data in a couchapp? Perhaps each user needs a uuid of some sort for
couchapps to reference (instead of using the username) so the conflict
winner still only gets to see their own data.

Can't quite decide how useful a single "users" database is. I imagine a user
would typically be expected to register with each couchapp? If those
couchapps happen to be hosted in the same couchdb then that means that the
user would have to come up with two (or more) usernames, because their
preferred username would already be taken by registering with the first
couchapp. Perhaps the user docs could include some sort of application id
that can be included in the users view (it could even emit username and
application+':'+username rows)?

A user can edit their own doc so I assume that means the design is to allow
for extra information in the docs, e.g. the user's real name, email address,
etc? Having that information in a different database to where the user's
actual data is stored seems quite limiting, e.g. for view collation to see
the user's name and postings. The solution is probably per-database users.

openid support would be cute. :)


Hope that all makes sense.


- Matt

Re: Initial couchdb accounts feedback

Posted by Brian Candler <B....@pobox.com>.
On Sun, Jan 10, 2010 at 07:05:59PM +0000, Brian Candler wrote:  
> I could of course frig the roles to include the db instance name, e.g.
>    "roles": ["db1:owner", "db2:read"]
> but:
> 
> (3) The 'owner' of a database needs to be able to grant access to other
> users. So bob@example.com, who has role db1:owner, needs to be able to
> grant
> or remove db1:<any> from any user on the system.
> 
> It would be fine if the roles were stored as document(s) within db1,
> because
> I could use validate_doc_update to allow anyone with the appropriate role
> to
> update them.
> 
> As couchdb is now, where the roles are stored within the global user[s]
> database, they can only be managed by a couchdb server administrator.

Actually, it looks like I should be able to replace _users/_design/_auth
with my own version, so I could implement a (systemwide) policy that role
'foo:admin' could add or remove role 'foo:bar' from any user.

The problem then becomes: within an application's validate_doc_update
function, how do I determine what database instance it is running within?
That is, a user might have role 'db1:bar' but I need to know whether I am
inside database db1 or not to decide whether they are authorized. I don't
think I can determine this from the parameters passed to
validate_doc_update.

Regards,

Brian.

Re: Initial couchdb accounts feedback

Posted by Simon Metson <si...@googlemail.com>.
Hi,
	I can imagine a database existing already with the name usr (or user,  
or auth), the name _usr (or _user or _auth) would be rarer (imho)  
exactly because the _ is already reserved in CouchDB. The _ databases  
will also sort and be next to one another, and all be special, whereas  
there may be other three letter databases beginning with u in the  
Couch, so I think the visual variation is better.
Cheers
Simon

On 10 Jan 2010, at 23:42, cinnebar wrote:

> I think its a worthwhile discussion to have but not sure if its  
> entirely
> relevent to this thread?
>
> breifly: limiting a set of keys to three letters, where other keys  
> are not
> makes keys from the set instantly uniquely disinguishable.  common  
> practice
> would be user or users so in the context usr is a unique identifier.
> whereas in "_users" the visual variation is a _ which is harder to
> distinguish in a list of names from user or users or other names using
> regular english terms for things you would want to keep in a db,  
> _imhos.
>
> (also i would hope that the question is more an effort to establish  
> best
> practice rather than lazy antagonism)
>
> cheers
>
>
>
> On Mon, Jan 11, 2010 at 6:38 AM, Noah Slater <ns...@tumbolia.org>  
> wrote:
>
>>
>> On 10 Jan 2010, at 19:19, cinnebar wrote:
>>
>>> i was talking about a set that is uniquely distinguishable, even  
>>> from the
>>> set using underscores
>>
>> What makes "usr" uniquely distinguishable in a way that "_users" is  
>> not?
>>
>> To quote Sam Ruby, and applying it to URLs (which are opaque  
>> buckets of 1s
>> and 0s), it's just data!


Re: Initial couchdb accounts feedback

Posted by cinnebar <cc...@gmail.com>.
I think its a worthwhile discussion to have but not sure if its entirely
relevent to this thread?

breifly: limiting a set of keys to three letters, where other keys are not
makes keys from the set instantly uniquely disinguishable.  common practice
would be user or users so in the context usr is a unique identifier.
whereas in "_users" the visual variation is a _ which is harder to
distinguish in a list of names from user or users or other names using
regular english terms for things you would want to keep in a db, _imhos.

(also i would hope that the question is more an effort to establish best
practice rather than lazy antagonism)

cheers



On Mon, Jan 11, 2010 at 6:38 AM, Noah Slater <ns...@tumbolia.org> wrote:

>
> On 10 Jan 2010, at 19:19, cinnebar wrote:
>
> > i was talking about a set that is uniquely distinguishable, even from the
> > set using underscores
>
> What makes "usr" uniquely distinguishable in a way that "_users" is not?
>
> To quote Sam Ruby, and applying it to URLs (which are opaque buckets of 1s
> and 0s), it's just data!

Re: Initial couchdb accounts feedback

Posted by Noah Slater <ns...@tumbolia.org>.
On 10 Jan 2010, at 19:19, cinnebar wrote:

> i was talking about a set that is uniquely distinguishable, even from the
> set using underscores

What makes "usr" uniquely distinguishable in a way that "_users" is not?

To quote Sam Ruby, and applying it to URLs (which are opaque buckets of 1s and 0s), it's just data!

Re: Initial couchdb accounts feedback

Posted by cinnebar <cc...@gmail.com>.
On Mon, Jan 11, 2010 at 6:07 AM, Noah Slater <ns...@tumbolia.org> wrote:

>
> On 10 Jan 2010, at 18:24, cinnebar wrote:
>
> > i agree but things like the name of the user db are structural
> underpinnings
> > rather than simple data so applying a naming convention to distinguish
> the
> > set actually improves readability and resolves other issues, in my
> > experience.
>
> We already have one! The underscore!
>
>
i was talking about a set that is uniquely distinguishable, even from the
set using underscores
but here the default is configuarable so if the underscore works for the
majority it should be the default

cheers

Re: Initial couchdb accounts feedback

Posted by Noah Slater <ns...@tumbolia.org>.
On 10 Jan 2010, at 18:24, cinnebar wrote:

> i agree but things like the name of the user db are structural underpinnings
> rather than simple data so applying a naming convention to distinguish the
> set actually improves readability and resolves other issues, in my
> experience.

We already have one! The underscore!


Re: Initial couchdb accounts feedback

Posted by cinnebar <cc...@gmail.com>.
technically it is the user db rather than the users db.

> _usr or _user would seem to make sense to me, since the _ is reserved
namespace in couchdb (e.g. _id and _rev).

> Yeah, "magic" fields should have a leading underscore to show they are
> in the reserved namespace, but let's not drop the 'e' in user, it's
> not the 60's anymore, we don't need to sacrifice readability to gain
> an extra byte.

i follow the logic of the pattern of underscoring feilds such as _id and
_rev but i dont think it follows that then the user db name should also be
underscored. if anything to maintain the pattern "roles" should be
underscored if its a reserved namespace field but i dont think this would be
necessarily justified.

what name is given to the user db appears to be more a question of common
practice and dogma in systems architecture rather than a sacrifice of
readibility. id and rev dont appear to sacrifice readibility.  convention
based on dogma is drag whichever era or social band spawned it.  succinct is
better for eg _id and _rev are readable but they are missing loads of
letters.


> 'usr' is typically from UNIX filesystem hierarchy, which is a horrendous
mess...

this relates more to the unix architecture than the particular use of 'usr'
methinks.

>  I quite like using full english names where that doesn't mean wasting too
much space.

i agree but things like the name of the user db are structural underpinnings
rather than simple data so applying a naming convention to distinguish the
set actually improves readability and resolves other issues, in my
experience.

we will be using 'usr' to name the user db no matter what, for a number of
reasons that may be unique to our doc/system architecture at present, the
only issue we have is that changing the hardcoded default a) would be an
irritating manual correction on each realease or b) a patch to allow
overriding the default may compromise security to some degree.

the only reason i am posting on this thread is because the changes
significantly affect our use of couchdb.
more time is needed to look into the issues here but chris seems to be
moving fast so...

Re: Initial couchdb accounts feedback

Posted by Matteo Caprari <ma...@gmail.com>.
Email addreses are bits of personal information and should be asked
and stored only when they are useful. Corporate apps often require a
registration but not an email.

Couchdb apps should 'usually work' when there's no internet connection.

-teo
On Sun, Jan 10, 2010 at 6:56 AM, Chris Anderson <jc...@apache.org> wrote:
> On Sat, Jan 9, 2010 at 2:17 PM, Brian Candler <B....@pobox.com> wrote:
>> On Sat, Jan 09, 2010 at 10:41:52AM -0800, Chris Anderson wrote:
>>> > Can't quite decide how useful a single "users" database is. I imagine a user
>>> > would typically be expected to register with each couchapp?
>>>
>>> The plan is that the user is logged into the node, not the db, so that
>>> CouchApp authors can just take for granted that the user is or isn't
>>> logged in, and never have to write any session management code
>>> themselves. If you are jchris when you use the calendar it make sense
>>> that you'd be jchris when you write a blog entry.
>>
>> However it's also possible that non-cooperating applications exist on the
>> same server.  In the limit, each database on a server could belong to a
>> different customer, and none of them trust each other. I wouldn't want to
>> have to run a separate couchdb server instance on a separate port for each
>> one.
>>
>> So given a single users database, then to make this work I think this
>> implies the following.
>>
>> 1. The usernames must be guaranteed *globally* unique - i.e. E-mail
>> addresses. Otherwise, app1's "bob" might be different to app2's "bob".
>>
>> 2. When you create a new account, the ownership of that handle must be
>> authenticated, by sending out an E-mail with an activation link.  (Looking
>> at the screencast, it seems that anyone can claim any username on a
>> first-come, first-served basis at the moment)
>>
>> 3. The 'roles' are really to do with authorization, not authentication. I
>> think that these belong with the databases themselves, not the users file.
>> For example, I think the prescription application should track of which
>> usernames have the 'doctor' role, not the users database.
>>
>> Consider also that setting roles is an application function, not a server
>> administrator function. For example, the health services manager might want
>> to be able to assign the 'doctor' role to certain individuals, without
>> having to get the server administrator involved.
>>
>> If the roles were a document or documents in the app database, this is easy
>> (validate_doc_update can know which role(s) are permitted to change the
>> role(s) of other users)
>>
>> Some consequences
>> -----------------
>>
>> On the plus side:
>>
>> * If the usernames were validated E-mail addresses, then I agree that having
>> a single users database is a bonus. That is, once signed up once, you are
>> ready to authenticate to any app on that server, and can switch between them
>> at will.
>
> I would *love* to see an easy email loop that CouchApps can access.
>
> I bet the Raindrop project has exactly the code you'd need to
> implement this as a CouchApp + external.
>
> I'm not sure about adding this complexity. What if the user is
> experiencing a network partition from their email provider? They
> should still be able to sign up.
>
>>
>> * If usernames were E-mail addresses, then most app writers will want to
>> have them validated, so building the activation-link logic into couchdb
>> will save them work. (However, each app might want to provide its own
>> E-mail template, so that the first signup is suitably "branded")
>>
>> * Keeping authentication separate from authorization, and in particular
>> storing roles within each database, would work well with OpenID which only
>> provides authentication.  That is, with OpenID we know *who* you are, but
>> still need to store locally *what* you can do.
>>
>> * Authorisations (role membership) could replicate with the application
>> itself
>>
>> On the minus side:
>>
>> * some schemes like LDAP *might* want to combine authentication and
>> authorization in the same database
>>
>> * if we kept the authorization centralised it means that, in principle, a
>> user could login and immediately see all the apps that they have access to.
>> That is, you could have roles per app but keep them in the users database:
>> e.g.
>>
>>    "username": "fred@example.com",
>>    "roles": {
>>        "prescriptions":['doctor'],
>>        "fredsblog":['blogadmin']
>>    }
>>
>> Futon can immediately guide the user to the apps which they have access to
>> (although there might also be public apps that can use).  But it makes it
>> hard to replicate the roles.
>>
>> * There is a middle ground, which is what I've actually implemented in my
>> own multi-database app: have a global users database which also contains one
>> authorization document per app database (mapping users to roles for that
>> db).  This means that I can still use a view to determine all databases a
>> user has access to when they login; and when I delete a database, I only
>> need to delete one document from the global database as well to get rid of
>> the related authorizations.
>>
>> I would have preferred to have the authorizations within each db, but this
>> wouldn't let me present the user with a list of the databases they can
>> access, without extracting this periodically.
>>
>> Regards,
>>
>> Brian.
>>
>> P.S. I'm not sure how the authentication code plugs in at the
>> moment.  Perhaps there could be an auth module which runs an external
>> process and talks to it over a socket, like a view server?  Then it would be
>> easy to implement things like sending out validation E-mails without having
>> to write it in Erlang.
>>
>> P.P.S. One other thought: when it is possible to restrict read access per
>> database, it would be nice to distinguish "not authorized" from "any
>> authorized user" - perhaps with a hardcode role which all authorized users
>> gain.
>>
>
>
>
> --
> Chris Anderson
> http://jchrisa.net
> http://couch.io
>



-- 
:Matteo Caprari
matteo.caprari@gmail.com

Re: Initial couchdb accounts feedback

Posted by Brian Candler <B....@pobox.com>.
> I'm not sure about adding this complexity. What if the user is
> experiencing a network partition from their email provider? They
> should still be able to sign up.

It seems the answer will be different for different people.

For me, the answer is that they absolutely should *not* be able to sign up
as this particular user, without being able to prove it is them. And this
goes to a matter of trust: if I add a role "doctor" to user
"fred@example.com", I need to be sure that "fred@example.com" really is the
person with that E-mail address, and not some imposter who happened to
choose that username just because they got to the server first.

I imagine the same will be true for any public hosting which sells space
for individual dbs on a shared couchdb instance.

But others have said they're quite happy to have first-come-first-served
non-validated usernames. So this is a matter of policy, and it needs to be
pluggable.

> I would *love* to see an easy email loop that CouchApps can access.
> 
> I bet the Raindrop project has exactly the code you'd need to
> implement this as a CouchApp + external.

But if you implement it as a couchapp, don't you have to trust the client? 
CouchApps are just regular clients, so if clients can insert random stuff
into the user[s] db, then you can't know that it's been properly validated. 
Hmm, or maybe the validate_doc_update can check for a signed cookie or
something like that (as long as you are very careful that the design doc for
the user[s] database is not readable!!)

What about my other point, that roles should be per database, not global?

Let me put it another way. I have an application here, currently written in
Rails, which has a separate couchdb database per customer.  It has a simple
rights model: the owner of a particular database can permit other users to
access it (either read-only, update, or owner level privileges).  When a
user logs in, they get to choose which of the database they have access to
that they'd like to work with.

It's starting to look like I could rip out a whole load of the application
concerned with signup, session and authorization handling - even turn the
whole thing into a couchapp, moving all the user interface into the client. 
But for me to be able to do this, the following would have to be possible:

(1) Usernames have to be securely linked to the individual. OpenID would be
fine, but that's too complicated for most people, so I'm using E-mail
address with activation link.  Otherwise, granting permissions to "bob"
could be granting it to anyone.

(2) Roles have to be per database. For example, "bob@example.com" might be
the owner of db1, have read access to db2, and no access at all to db3.

I could of course frig the roles to include the db instance name, e.g.
   "roles": ["db1:owner", "db2:read"]
but:

(3) The 'owner' of a database needs to be able to grant access to other
users. So bob@example.com, who has role db1:owner, needs to be able to grant
or remove db1:<any> from any user on the system.

It would be fine if the roles were stored as document(s) within db1, because
I could use validate_doc_update to allow anyone with the appropriate role to
update them.

As couchdb is now, where the roles are stored within the global user[s]
database, they can only be managed by a couchdb server administrator. So
this would mean I'd have to have a middleware program running with server
admin privileges by which user X could request a grant/revoke of role R to
user Y on database Z. And what's tricky is that the user X would have to be
able to prove their identity to that middleware app when sending the
request.

Right now, I can't move the authentication and even this coarse level of
authorization into couchdb, and therefore I can't expose couchdb to the
world without the middleware layer.

Note that I'll still need a small trusted middleware program running as
couchdb server admin, which would be used for creating new databases (and
perhaps also billing them), and deleting ones which are no longer required.

Regards,

Brian.

Re: Initial couchdb accounts feedback

Posted by Chris Anderson <jc...@apache.org>.
On Sat, Jan 9, 2010 at 2:17 PM, Brian Candler <B....@pobox.com> wrote:
> On Sat, Jan 09, 2010 at 10:41:52AM -0800, Chris Anderson wrote:
>> > Can't quite decide how useful a single "users" database is. I imagine a user
>> > would typically be expected to register with each couchapp?
>>
>> The plan is that the user is logged into the node, not the db, so that
>> CouchApp authors can just take for granted that the user is or isn't
>> logged in, and never have to write any session management code
>> themselves. If you are jchris when you use the calendar it make sense
>> that you'd be jchris when you write a blog entry.
>
> However it's also possible that non-cooperating applications exist on the
> same server.  In the limit, each database on a server could belong to a
> different customer, and none of them trust each other. I wouldn't want to
> have to run a separate couchdb server instance on a separate port for each
> one.
>
> So given a single users database, then to make this work I think this
> implies the following.
>
> 1. The usernames must be guaranteed *globally* unique - i.e. E-mail
> addresses. Otherwise, app1's "bob" might be different to app2's "bob".
>
> 2. When you create a new account, the ownership of that handle must be
> authenticated, by sending out an E-mail with an activation link.  (Looking
> at the screencast, it seems that anyone can claim any username on a
> first-come, first-served basis at the moment)
>
> 3. The 'roles' are really to do with authorization, not authentication. I
> think that these belong with the databases themselves, not the users file.
> For example, I think the prescription application should track of which
> usernames have the 'doctor' role, not the users database.
>
> Consider also that setting roles is an application function, not a server
> administrator function. For example, the health services manager might want
> to be able to assign the 'doctor' role to certain individuals, without
> having to get the server administrator involved.
>
> If the roles were a document or documents in the app database, this is easy
> (validate_doc_update can know which role(s) are permitted to change the
> role(s) of other users)
>
> Some consequences
> -----------------
>
> On the plus side:
>
> * If the usernames were validated E-mail addresses, then I agree that having
> a single users database is a bonus. That is, once signed up once, you are
> ready to authenticate to any app on that server, and can switch between them
> at will.

I would *love* to see an easy email loop that CouchApps can access.

I bet the Raindrop project has exactly the code you'd need to
implement this as a CouchApp + external.

I'm not sure about adding this complexity. What if the user is
experiencing a network partition from their email provider? They
should still be able to sign up.

>
> * If usernames were E-mail addresses, then most app writers will want to
> have them validated, so building the activation-link logic into couchdb
> will save them work. (However, each app might want to provide its own
> E-mail template, so that the first signup is suitably "branded")
>
> * Keeping authentication separate from authorization, and in particular
> storing roles within each database, would work well with OpenID which only
> provides authentication.  That is, with OpenID we know *who* you are, but
> still need to store locally *what* you can do.
>
> * Authorisations (role membership) could replicate with the application
> itself
>
> On the minus side:
>
> * some schemes like LDAP *might* want to combine authentication and
> authorization in the same database
>
> * if we kept the authorization centralised it means that, in principle, a
> user could login and immediately see all the apps that they have access to.
> That is, you could have roles per app but keep them in the users database:
> e.g.
>
>    "username": "fred@example.com",
>    "roles": {
>        "prescriptions":['doctor'],
>        "fredsblog":['blogadmin']
>    }
>
> Futon can immediately guide the user to the apps which they have access to
> (although there might also be public apps that can use).  But it makes it
> hard to replicate the roles.
>
> * There is a middle ground, which is what I've actually implemented in my
> own multi-database app: have a global users database which also contains one
> authorization document per app database (mapping users to roles for that
> db).  This means that I can still use a view to determine all databases a
> user has access to when they login; and when I delete a database, I only
> need to delete one document from the global database as well to get rid of
> the related authorizations.
>
> I would have preferred to have the authorizations within each db, but this
> wouldn't let me present the user with a list of the databases they can
> access, without extracting this periodically.
>
> Regards,
>
> Brian.
>
> P.S. I'm not sure how the authentication code plugs in at the
> moment.  Perhaps there could be an auth module which runs an external
> process and talks to it over a socket, like a view server?  Then it would be
> easy to implement things like sending out validation E-mails without having
> to write it in Erlang.
>
> P.P.S. One other thought: when it is possible to restrict read access per
> database, it would be nice to distinguish "not authorized" from "any
> authorized user" - perhaps with a hardcode role which all authorized users
> gain.
>



-- 
Chris Anderson
http://jchrisa.net
http://couch.io

Re: Initial couchdb accounts feedback

Posted by Brian Candler <B....@pobox.com>.
On Sat, Jan 09, 2010 at 10:41:52AM -0800, Chris Anderson wrote:
> > Can't quite decide how useful a single "users" database is. I imagine a user
> > would typically be expected to register with each couchapp?
> 
> The plan is that the user is logged into the node, not the db, so that
> CouchApp authors can just take for granted that the user is or isn't
> logged in, and never have to write any session management code
> themselves. If you are jchris when you use the calendar it make sense
> that you'd be jchris when you write a blog entry.

However it's also possible that non-cooperating applications exist on the
same server.  In the limit, each database on a server could belong to a
different customer, and none of them trust each other. I wouldn't want to
have to run a separate couchdb server instance on a separate port for each
one.

So given a single users database, then to make this work I think this
implies the following.

1. The usernames must be guaranteed *globally* unique - i.e. E-mail
addresses. Otherwise, app1's "bob" might be different to app2's "bob".

2. When you create a new account, the ownership of that handle must be
authenticated, by sending out an E-mail with an activation link.  (Looking
at the screencast, it seems that anyone can claim any username on a
first-come, first-served basis at the moment)

3. The 'roles' are really to do with authorization, not authentication. I
think that these belong with the databases themselves, not the users file. 
For example, I think the prescription application should track of which
usernames have the 'doctor' role, not the users database.

Consider also that setting roles is an application function, not a server
administrator function. For example, the health services manager might want
to be able to assign the 'doctor' role to certain individuals, without
having to get the server administrator involved.

If the roles were a document or documents in the app database, this is easy
(validate_doc_update can know which role(s) are permitted to change the
role(s) of other users)

Some consequences
-----------------

On the plus side:

* If the usernames were validated E-mail addresses, then I agree that having
a single users database is a bonus. That is, once signed up once, you are
ready to authenticate to any app on that server, and can switch between them
at will.

* If usernames were E-mail addresses, then most app writers will want to
have them validated, so building the activation-link logic into couchdb
will save them work. (However, each app might want to provide its own
E-mail template, so that the first signup is suitably "branded")

* Keeping authentication separate from authorization, and in particular
storing roles within each database, would work well with OpenID which only
provides authentication.  That is, with OpenID we know *who* you are, but
still need to store locally *what* you can do.

* Authorisations (role membership) could replicate with the application
itself

On the minus side:

* some schemes like LDAP *might* want to combine authentication and
authorization in the same database

* if we kept the authorization centralised it means that, in principle, a
user could login and immediately see all the apps that they have access to. 
That is, you could have roles per app but keep them in the users database:
e.g.

    "username": "fred@example.com",
    "roles": {
        "prescriptions":['doctor'],
        "fredsblog":['blogadmin']
    }

Futon can immediately guide the user to the apps which they have access to
(although there might also be public apps that can use).  But it makes it
hard to replicate the roles.

* There is a middle ground, which is what I've actually implemented in my
own multi-database app: have a global users database which also contains one
authorization document per app database (mapping users to roles for that
db).  This means that I can still use a view to determine all databases a
user has access to when they login; and when I delete a database, I only
need to delete one document from the global database as well to get rid of
the related authorizations.

I would have preferred to have the authorizations within each db, but this
wouldn't let me present the user with a list of the databases they can
access, without extracting this periodically.

Regards,

Brian.

P.S. I'm not sure how the authentication code plugs in at the
moment.  Perhaps there could be an auth module which runs an external
process and talks to it over a socket, like a view server?  Then it would be
easy to implement things like sending out validation E-mails without having
to write it in Erlang.

P.P.S. One other thought: when it is possible to restrict read access per
database, it would be nice to distinguish "not authorized" from "any
authorized user" - perhaps with a hardcode role which all authorized users
gain.

Re: Initial couchdb accounts feedback

Posted by cinnebar <cc...@gmail.com>.
On Mon, Jan 11, 2010 at 5:24 AM, cinnebar <cc...@gmail.com> wrote:
>validate against a"'cat" field which effectively means that user is a type
of namespaced role and other roles are also values keyed by "cat"

this is false.
at the moment the relevent fields of the usr doc we are working with look
like this:

"cat":"usr"
"env":{"cat":[/*roles*/)], ...}

'usr' is a document category whereas 'env.cat' in a 'usr' document is a user
category.



On Fri, Jan 15, 2010 at 3:54 AM, Chris Anderson <jc...@apache.org> wrote:

> On Thu, Jan 14, 2010 at 1:38 AM, Brian Candler <B....@pobox.com>
> wrote:
> > Some more thoughts about the "_users" database.
> >
> > (1) It has been suggested in another thread that one user may have
> multiple
> > identities - in particular, multiple openids - and want to be able to
> login
> > with any of them.
> >
> > Or, someone could sign in with an E-mail address initially, and then want
> to
> > add a second E-mail address to their account, because they are changing
> > E-mail provider.
> >
> > Now, if the _users database were not queried directly, but instead via a
> > view, this would allow the flexibility to have different structures, e.g.
> >
> >    "_id":"0cf34232937c7d2a",
> >    "identities":["fred@example.com","fred@example.net"]
> >
> > I think this solves the replication problem nicely too. If two different
> > users have username:"bob" (but different uuids), then after replication a
> > login query will return two rows, and they won't be able to login.  The
> > admin can fix this easily, either by altering one of the identities, or
> by
> > deleting one of the user documents.
>
> I'd rather treat conflicts as conflicts. I've got on my list of TODOs,
> to make conflict docs ignored for purposes of login.
>
> >
> > The major flaw with this idea is that you can't prevent dupes at signup,
> > since validate_doc_update can't check a view first.
> >
> > (2) Given that there are different types of identities, it might make
> sense
> > to namespace them:
> >
> >        "login:fred"
> >        "email:foo@example.com <em...@example.com>"
> >        "openid:fred@example.net <op...@example.net>"
> >
> > Having said that, I don't expect that the user with E-mail
> fred@example.com
> > would be different from the user with openid fred@example.com - and if
> they
> > were, it would be a bit confusing.
> >
> > (3) In principle it's easy to plug in so that the identities can be
> > validated if required.  For example, an external process which validates
> > that you have E-mail foo@example.com could E-mail you a message
> containing a
> > signed token which says you own email:foo@example.com<em...@example.com>.
> We block users adding
> > an "email:..." identity without this token.
> >
> > Doing that requires some way of validating the token in
> validate_doc_update.
> > * We can't use a hmac_sha1 + hardcoded secret, because anyone who reads
> the
> >  _design document will know the secret
> > * Doing RSA signature verification in Javascript could be tricky
> > * Both may be expensive in Javascript
> > * In any case we don't want to hardcode individual keys in the
> >  server's validate_doc_update function
> >
> > I can think of several solutions. One is that a server secret is passed
> as a
> > parameter to validate_doc_update (perhaps as part of the "security
> context"
> > mentioned before). Another is that the server checks some field of the
> > userDoc for a signature, and strips it if it's not properly signed. There
> > are probably better ideas floating around.
> >
> > I think what's needed is something *like* a cookie, which can be
> generated
> > by an external process and validated by couchdb.  Perhaps even the
> existing
> > cookie auth mechanism could be overloaded/abused.  Put simply:
> > validate_doc_update won't let you create user "foo@example.com" unless
> it
> > sees that you are already logged in as "foo@example.com". That's trivial
> to
> > implement.
> >
> > (But this gets complicated for multiple identities, as you would need two
> > cookies at once to add your new ID to your existing reecord).
> >
> > At worst, you could always have an _external handler which knows the
> _admin
> > credentials to the database, which in turn makes a HTTP call back to
> couchdb
> > to modify the user record.  I feel uncomfortable with couchdb eating its
> own
> > tail in this way.
> >
> > Since my app creates a new database per user, the 'signup' process would
> > ultimately have to work this way anyway, I think. But this shouldn't be
> > necessary for adding users to an existing database.
> >
> > Thoughts?
>
> This is all to complex for my just awakened brain. I don't think
> there's anything wrong with what you've just described, but it gets
> some of the complexity in the wrong places. The validate_doc_update
> function will just get a bare bones userCtx (name and roles) so adding
> other structure to the users db won't effect it. If your app has users
> which shouldn't be able to save documents until they have clicked a
> link in their email, then you should have a role of "email
> confirmation pending" and when the user clicks the link, some
> admin-level software can remove that role and add a "confirmed" role.
>
> I think we'll be able to support you, but I'll be trying hard to keep
> the stuff Couch ships with as simple as possible. The goal is to make
> the kinds of workflows you describe easy to layer on top of the
> default system, while maintaining security and scalability.
>
> >
> > Regards,
> >
> > Brian.
> >
> > P.S. In my current application (with its own user docs) I also store user
> > preferences, e.g.  timezone, full name.
> >
> > As far as I can see, the _users validate_doc_update lets you add
> arbitrary
> > data to the _users database, e.g.
> >    "foo_app_prefs":{"views_per_page":10}
> >
> > Would that be considered legitimate use for it, or is it likely to be
> locked
> > down in future?
> >
>
> I think it is better practice to store app specific profile data in
> another database. If you have site-specific profile data, it'd be OK
> to store it in the users db, but I'd still encourage you to use an app
> "site-profiles" and a db for that sort of thing. Maybe the users db
> will be locked down in the future (that may end up being a site
> setting.)
>
> Chris
>
> --
> Chris Anderson
> http://jchrisa.net
> http://couch.io
>

Re: Initial couchdb accounts feedback

Posted by Chris Anderson <jc...@apache.org>.
On Thu, Jan 14, 2010 at 1:38 AM, Brian Candler <B....@pobox.com> wrote:
> Some more thoughts about the "_users" database.
>
> (1) It has been suggested in another thread that one user may have multiple
> identities - in particular, multiple openids - and want to be able to login
> with any of them.
>
> Or, someone could sign in with an E-mail address initially, and then want to
> add a second E-mail address to their account, because they are changing
> E-mail provider.
>
> Now, if the _users database were not queried directly, but instead via a
> view, this would allow the flexibility to have different structures, e.g.
>
>    "_id":"0cf34232937c7d2a",
>    "identities":["fred@example.com","fred@example.net"]
>
> I think this solves the replication problem nicely too. If two different
> users have username:"bob" (but different uuids), then after replication a
> login query will return two rows, and they won't be able to login.  The
> admin can fix this easily, either by altering one of the identities, or by
> deleting one of the user documents.

I'd rather treat conflicts as conflicts. I've got on my list of TODOs,
to make conflict docs ignored for purposes of login.

>
> The major flaw with this idea is that you can't prevent dupes at signup,
> since validate_doc_update can't check a view first.
>
> (2) Given that there are different types of identities, it might make sense
> to namespace them:
>
>        "login:fred"
>        "email:foo@example.com"
>        "openid:fred@example.net"
>
> Having said that, I don't expect that the user with E-mail fred@example.com
> would be different from the user with openid fred@example.com - and if they
> were, it would be a bit confusing.
>
> (3) In principle it's easy to plug in so that the identities can be
> validated if required.  For example, an external process which validates
> that you have E-mail foo@example.com could E-mail you a message containing a
> signed token which says you own email:foo@example.com. We block users adding
> an "email:..." identity without this token.
>
> Doing that requires some way of validating the token in validate_doc_update.
> * We can't use a hmac_sha1 + hardcoded secret, because anyone who reads the
>  _design document will know the secret
> * Doing RSA signature verification in Javascript could be tricky
> * Both may be expensive in Javascript
> * In any case we don't want to hardcode individual keys in the
>  server's validate_doc_update function
>
> I can think of several solutions. One is that a server secret is passed as a
> parameter to validate_doc_update (perhaps as part of the "security context"
> mentioned before). Another is that the server checks some field of the
> userDoc for a signature, and strips it if it's not properly signed. There
> are probably better ideas floating around.
>
> I think what's needed is something *like* a cookie, which can be generated
> by an external process and validated by couchdb.  Perhaps even the existing
> cookie auth mechanism could be overloaded/abused.  Put simply:
> validate_doc_update won't let you create user "foo@example.com" unless it
> sees that you are already logged in as "foo@example.com". That's trivial to
> implement.
>
> (But this gets complicated for multiple identities, as you would need two
> cookies at once to add your new ID to your existing reecord).
>
> At worst, you could always have an _external handler which knows the _admin
> credentials to the database, which in turn makes a HTTP call back to couchdb
> to modify the user record.  I feel uncomfortable with couchdb eating its own
> tail in this way.
>
> Since my app creates a new database per user, the 'signup' process would
> ultimately have to work this way anyway, I think. But this shouldn't be
> necessary for adding users to an existing database.
>
> Thoughts?

This is all to complex for my just awakened brain. I don't think
there's anything wrong with what you've just described, but it gets
some of the complexity in the wrong places. The validate_doc_update
function will just get a bare bones userCtx (name and roles) so adding
other structure to the users db won't effect it. If your app has users
which shouldn't be able to save documents until they have clicked a
link in their email, then you should have a role of "email
confirmation pending" and when the user clicks the link, some
admin-level software can remove that role and add a "confirmed" role.

I think we'll be able to support you, but I'll be trying hard to keep
the stuff Couch ships with as simple as possible. The goal is to make
the kinds of workflows you describe easy to layer on top of the
default system, while maintaining security and scalability.

>
> Regards,
>
> Brian.
>
> P.S. In my current application (with its own user docs) I also store user
> preferences, e.g.  timezone, full name.
>
> As far as I can see, the _users validate_doc_update lets you add arbitrary
> data to the _users database, e.g.
>    "foo_app_prefs":{"views_per_page":10}
>
> Would that be considered legitimate use for it, or is it likely to be locked
> down in future?
>

I think it is better practice to store app specific profile data in
another database. If you have site-specific profile data, it'd be OK
to store it in the users db, but I'd still encourage you to use an app
"site-profiles" and a db for that sort of thing. Maybe the users db
will be locked down in the future (that may end up being a site
setting.)

Chris

-- 
Chris Anderson
http://jchrisa.net
http://couch.io

Re: Initial couchdb accounts feedback

Posted by Brian Candler <B....@pobox.com>.
On Tue, Jan 19, 2010 at 06:31:29PM +0000, Brian Candler wrote:
> What I was thinking is that you could give the user a cookie, signed using
> the same algorithm and secret as the HTTP cookie auth module; they could
> then login using this cookie, and once logged in create their account.

... and the reason for doing this is it's not easy to validate some other
ephemeral token in validate_doc_update, especially if the design doc is
world readable (in any case, who wants to do an HMAC-SHA1 or RSA signature
check in Javascript? :-)

However I'm totally open to other suggestions for this.

Re: Initial couchdb accounts feedback

Posted by Brian Candler <B....@pobox.com>.
On Tue, Jan 19, 2010 at 05:09:39PM +0000, Jason Davies wrote:
> See below for my comments.  I'm not really sure why the ability to
> generate a valid cookie externally is needed, perhaps you can explain a
> bit more about that?

It's for the following scenario: you want all usernames in the database to
be validated, rather than a first-come-first-served free-for-all.

So you need to validate the username, and then give the user some sort of
token that says it's valid and they can go ahead and create the account.

What I was thinking is that you could give the user a cookie, signed using
the same algorithm and secret as the HTTP cookie auth module; they could
then login using this cookie, and once logged in create their account.

The policy in validate_doc_update would be "you can't create account for
username foo unless the userCtx says you're already logged in as foo".

It minimises the amount of couchdb interaction which would have to be done
by a process with _admin rights.

> The session cookie is signed to prevent tampering using
> HMAC-SHA1(<server-wide secret> + <user salt>, <username, timestamp>).  The
> combination of server-wide secret and user-specific secret marginally
> increases the difficulty of attacks based on obtaining the server-wide
> secret.  Or alternatively, if the combined secret could be obtained
> somehow (perhaps with great effort, using cryptanalysis!) this would not
> give the attacker "access all areas" as they wouldn't have the other user
> salts.

Except that _users is world-readable at the moment :-)

> The main reason, though, is this allows an individual user's session(s) to
> be invalidated simply by changing their salt.  For example, GMail lets you
> log out all other sessions, and this provides similar functionality.

Ah, well that's interesting - you want to terminate someone's access fully,
and ensure there are no rights lingering on.

At the moment, rather than change the salt, you could just delete the user
record.  Your code will look for the salt and not find the user at all and
reject on that basis alone.  It's certainly an argument for requiring the
user account to exist.

BTW, sorry I didn't notice you were already using HMAC-SHA1. I must have
been blind when reading the code.

[cookie expiration time]
> This sounds fine to me, I think originally I wanted to keep the expiration
> times low to reduce the possibility of replay attacks.

I don't think it makes much difference. Actually, I think I could issue a
72-hour cookie already, because I don't think that the validation code
checks for times in the future. Maybe they should have both start and end
times?

Also, having an explicit expiration time might allow things like different
session timeouts for different dbs or users.

Regards,

Brian.

Re: Initial couchdb accounts feedback

Posted by Jason Davies <ja...@jasondavies.com>.
Hi Brian,

On 14 Jan 2010, at 17:23, Chris Anderson wrote:

> On Thu, Jan 14, 2010 at 9:08 AM, Brian Candler <B....@pobox.com> wrote:
>> [Carried over from user@; thoughts on requiring users to validate their
>> E-mail address as a username]
>> 
>> On Thu, Jan 14, 2010 at 09:38:34AM +0000, Brian Candler wrote:
>>> I think what's needed is something *like* a cookie, which can be generated
>>> by an external process and validated by couchdb.  Perhaps even the existing
>>> cookie auth mechanism could be overloaded/abused.  Put simply:
>>> validate_doc_update won't let you create user "foo@example.com" unless it
>>> sees that you are already logged in as "foo@example.com". That's trivial to
>>> implement.
>> 
>> I've had a go at implementing this, and the attached patch includes tests
>> for this way of working. (*)
> 
> I'd be interested in seeing what Jason Davies thinks. My first guess
> is that the salt is in the cookie to add entropy and make guessing the
> server secret harder.

See below for my comments.  I'm not really sure why the ability to generate a valid cookie externally is needed, perhaps you can explain a bit more about that?

>> 
>> The good news:
>> 
>> * because validate_doc_update is stackable, it's very easy to add your own
>> policies for valid usernames, just by adding another design doc with its own
>> validate_doc_update.
>> 
>> * if you send someone an auth cookie via E-mail, not only does that validate
>> their E-mail address, but it solves the "forgotten password" problem too
>> (just ask the system to E-mail you another cookie, login, and change your
>> password).
>> 
>> There are a couple of issues though.
>> 
>> (1) I found that the cookie_authentication_handler would not let you login,
>> even if your cookie was valid, if you did not already have an entry in the
>> users database. It turns out this is because it looks up user's salt and
>> includes it in the cookie hash.
>> 
>> I can't see a justification for that, so in the attached patch I have
>> removed it.  Please correct me if I've overlooked something.

The session cookie is signed to prevent tampering using HMAC-SHA1(<server-wide secret> + <user salt>, <username, timestamp>).  The combination of server-wide secret and user-specific secret marginally increases the difficulty of attacks based on obtaining the server-wide secret.  Or alternatively, if the combined secret could be obtained somehow (perhaps with great effort, using cryptanalysis!) this would not give the attacker "access all areas" as they wouldn't have the other user salts.

The main reason, though, is this allows an individual user's session(s) to be invalidated simply by changing their salt.  For example, GMail lets you log out all other sessions, and this provides similar functionality.

If this is too limiting perhaps we can find a way to support session cookies that don't sign using the user salt.

>> 
>> (I think what *would* improve security would be using a HMAC_SHA1 instead of
>> a plain SHA1 with the server secret: see RFC 2104, RFC 2202)
>> 
>> (2) The cookie currently holds the time it was created, not the time it
>> expires.  It would be very useful if you could E-mail out a cookie with an
>> expiry time further in the future (say 72 hours), whilst still leaving http
>> cookies at 10 minutes.
>> 
>> Making the cookie carry the expiry time would be straightforward to change.
>> Are you happy for me to do so?
> 
> this sounds sensible to me. Jason?

This sounds fine to me, I think originally I wanted to keep the expiration times low to reduce the possibility of replay attacks.  I have some ideas about preventing these using nonces anyway, but haven't had time to implement them.  I don't know if they would throw a spanner in the works if you want to generate the session externally though.

> 
>> 
>> Regards,
>> 
>> Brian.
>> 
>> (*) You still need an _external handler to calculate the cookie and E-mail
>> it out, and to convert the activation link into a Set-Cookie

Sending a 72-hour session cookie via email sounds rather dubious from a security standpoint, as an attacker could then gain indefinite access by constantly refreshing his session cookie with new expiry timestamps.

>> 
> 
> 
> 
> -- 
> Chris Anderson
> http://jchrisa.net
> http://couch.io

--
Jason Davies

www.jasondavies.com


Re: Initial couchdb accounts feedback

Posted by Chris Anderson <jc...@apache.org>.
On Thu, Jan 14, 2010 at 9:08 AM, Brian Candler <B....@pobox.com> wrote:
> [Carried over from user@; thoughts on requiring users to validate their
> E-mail address as a username]
>
> On Thu, Jan 14, 2010 at 09:38:34AM +0000, Brian Candler wrote:
>> I think what's needed is something *like* a cookie, which can be generated
>> by an external process and validated by couchdb.  Perhaps even the existing
>> cookie auth mechanism could be overloaded/abused.  Put simply:
>> validate_doc_update won't let you create user "foo@example.com" unless it
>> sees that you are already logged in as "foo@example.com". That's trivial to
>> implement.
>
> I've had a go at implementing this, and the attached patch includes tests
> for this way of working. (*)

I'd be interested in seeing what Jason Davies thinks. My first guess
is that the salt is in the cookie to add entropy and make guessing the
server secret harder.

>
> The good news:
>
> * because validate_doc_update is stackable, it's very easy to add your own
> policies for valid usernames, just by adding another design doc with its own
> validate_doc_update.
>
> * if you send someone an auth cookie via E-mail, not only does that validate
> their E-mail address, but it solves the "forgotten password" problem too
> (just ask the system to E-mail you another cookie, login, and change your
> password).
>
> There are a couple of issues though.
>
> (1) I found that the cookie_authentication_handler would not let you login,
> even if your cookie was valid, if you did not already have an entry in the
> users database. It turns out this is because it looks up user's salt and
> includes it in the cookie hash.
>
> I can't see a justification for that, so in the attached patch I have
> removed it.  Please correct me if I've overlooked something.
>
> (I think what *would* improve security would be using a HMAC_SHA1 instead of
> a plain SHA1 with the server secret: see RFC 2104, RFC 2202)
>
> (2) The cookie currently holds the time it was created, not the time it
> expires.  It would be very useful if you could E-mail out a cookie with an
> expiry time further in the future (say 72 hours), whilst still leaving http
> cookies at 10 minutes.
>
> Making the cookie carry the expiry time would be straightforward to change.
> Are you happy for me to do so?

this sounds sensible to me. Jason?

>
> Regards,
>
> Brian.
>
> (*) You still need an _external handler to calculate the cookie and E-mail
> it out, and to convert the activation link into a Set-Cookie
>



-- 
Chris Anderson
http://jchrisa.net
http://couch.io

Re: Initial couchdb accounts feedback

Posted by Brian Candler <B....@pobox.com>.
[Carried over from user@; thoughts on requiring users to validate their
E-mail address as a username]

On Thu, Jan 14, 2010 at 09:38:34AM +0000, Brian Candler wrote:
> I think what's needed is something *like* a cookie, which can be generated
> by an external process and validated by couchdb.  Perhaps even the existing
> cookie auth mechanism could be overloaded/abused.  Put simply:
> validate_doc_update won't let you create user "foo@example.com" unless it
> sees that you are already logged in as "foo@example.com". That's trivial to
> implement.

I've had a go at implementing this, and the attached patch includes tests
for this way of working. (*)

The good news:

* because validate_doc_update is stackable, it's very easy to add your own
policies for valid usernames, just by adding another design doc with its own
validate_doc_update.

* if you send someone an auth cookie via E-mail, not only does that validate
their E-mail address, but it solves the "forgotten password" problem too
(just ask the system to E-mail you another cookie, login, and change your
password).

There are a couple of issues though.

(1) I found that the cookie_authentication_handler would not let you login,
even if your cookie was valid, if you did not already have an entry in the
users database. It turns out this is because it looks up user's salt and
includes it in the cookie hash.

I can't see a justification for that, so in the attached patch I have
removed it.  Please correct me if I've overlooked something.

(I think what *would* improve security would be using a HMAC_SHA1 instead of
a plain SHA1 with the server secret: see RFC 2104, RFC 2202)

(2) The cookie currently holds the time it was created, not the time it
expires.  It would be very useful if you could E-mail out a cookie with an
expiry time further in the future (say 72 hours), whilst still leaving http
cookies at 10 minutes.

Making the cookie carry the expiry time would be straightforward to change.
Are you happy for me to do so?

Regards,

Brian.

(*) You still need an _external handler to calculate the cookie and E-mail
it out, and to convert the activation link into a Set-Cookie

Re: Initial couchdb accounts feedback

Posted by Brian Candler <B....@pobox.com>.
Some more thoughts about the "_users" database.

(1) It has been suggested in another thread that one user may have multiple
identities - in particular, multiple openids - and want to be able to login
with any of them.

Or, someone could sign in with an E-mail address initially, and then want to
add a second E-mail address to their account, because they are changing
E-mail provider.

Now, if the _users database were not queried directly, but instead via a
view, this would allow the flexibility to have different structures, e.g.

    "_id":"0cf34232937c7d2a",
    "identities":["fred@example.com","fred@example.net"]

I think this solves the replication problem nicely too. If two different
users have username:"bob" (but different uuids), then after replication a
login query will return two rows, and they won't be able to login.  The
admin can fix this easily, either by altering one of the identities, or by
deleting one of the user documents.

The major flaw with this idea is that you can't prevent dupes at signup,
since validate_doc_update can't check a view first.

(2) Given that there are different types of identities, it might make sense
to namespace them:

        "login:fred"
        "email:foo@example.com"
        "openid:fred@example.net"

Having said that, I don't expect that the user with E-mail fred@example.com
would be different from the user with openid fred@example.com - and if they
were, it would be a bit confusing.

(3) In principle it's easy to plug in so that the identities can be
validated if required.  For example, an external process which validates
that you have E-mail foo@example.com could E-mail you a message containing a
signed token which says you own email:foo@example.com. We block users adding
an "email:..." identity without this token.

Doing that requires some way of validating the token in validate_doc_update.
* We can't use a hmac_sha1 + hardcoded secret, because anyone who reads the
  _design document will know the secret
* Doing RSA signature verification in Javascript could be tricky
* Both may be expensive in Javascript
* In any case we don't want to hardcode individual keys in the
  server's validate_doc_update function

I can think of several solutions. One is that a server secret is passed as a
parameter to validate_doc_update (perhaps as part of the "security context"
mentioned before). Another is that the server checks some field of the
userDoc for a signature, and strips it if it's not properly signed. There
are probably better ideas floating around.

I think what's needed is something *like* a cookie, which can be generated
by an external process and validated by couchdb.  Perhaps even the existing
cookie auth mechanism could be overloaded/abused.  Put simply:
validate_doc_update won't let you create user "foo@example.com" unless it
sees that you are already logged in as "foo@example.com". That's trivial to
implement.

(But this gets complicated for multiple identities, as you would need two
cookies at once to add your new ID to your existing reecord).

At worst, you could always have an _external handler which knows the _admin
credentials to the database, which in turn makes a HTTP call back to couchdb
to modify the user record.  I feel uncomfortable with couchdb eating its own
tail in this way.

Since my app creates a new database per user, the 'signup' process would
ultimately have to work this way anyway, I think. But this shouldn't be
necessary for adding users to an existing database.

Thoughts?

Regards,

Brian.

P.S. In my current application (with its own user docs) I also store user
preferences, e.g.  timezone, full name.

As far as I can see, the _users validate_doc_update lets you add arbitrary
data to the _users database, e.g.
    "foo_app_prefs":{"views_per_page":10}

Would that be considered legitimate use for it, or is it likely to be locked
down in future?

Re: Initial couchdb accounts feedback

Posted by Brian Candler <B....@pobox.com>.
On Sat, Jan 09, 2010 at 07:09:08PM -0800, Chris Anderson wrote:
> > I had a bit of a think about this overnight (since I'll be running in
> > this scenario). If there are dbs that shouldn't share users, perhaps
> > you could prefix the role with the appname. ie: { roles:
> > ["myapp1:editor"] }. Then once there are reader ACLs, you could test
> > that the user included roles with the appropriate prefix.

Having thought a bit more about that, it would work for me too, as long as
the app itself knew that it was called 'myapp1', or else the myapp1: prefix
were stripped from the role before being handed to the application.

Furthermore, if this were made a standard way of mapping app-specific roles,
then you could bundle a well-tested _users/_design/_auth function which
implements the myapp1:admin role.  It's a little hairy so worth doing right.

By the way, once db read access is controlled, is it planned that _all_dbs
should show only the databases to which the user has access? That would be
extremely useful.

> Currently the validation function takes 3 arguments (newDoc, diskDoc, userCtx)
> 
> The plan is to add a 4th argument, which is a security object. It
> would be per-app, and could allow a site (I'm thinking an office or
> some other organization) to map from site-roles to app-roles. So in
> the case of a hospital, you'd set up a mapping between various site
> roles like R.N., M.D., orderly, etc, and application roles
> (prescription-writer, prescription-filler, etc in the prescription
> app.)

Perhaps what you've written could be more clearly expressed as
   users -> groups; groups -> app roles.

I wouldn't need that myself, but I can see how it would be useful in
situations where all the apps on a server are in the same administrative
domain. All I need is users -> app roles (which could be implemented in
tandem with the above, of course)

If there are going to be groups, then you need more documents. The obvious
solution would be a group doc as well as a user doc:

    "type":"user",
    "username":"fred@example.com",
    "groups":["rn","orderly"],          # user -> group(s)
    "roles":["prescriptions:admin"],    # user -> app role(s)

    "type":"group",
    "groupname":"rn",
    "roles":["prescriptions":"create"]  # group -> app role(s)

But could you also consider one document per *application*:

    "type":"user",
    "username":"fred@example.com",
    "groups":["rn","orderly"]

    "type":"authz",
    "db":"prescriptions",        # the name of the database
    "users:{
       "fred@example.com": ["admin"],
    },
    "groups":{
       "rn": ["create"],
    }

Then when you clone/replicate/delete a database, there is only one authz doc
which needs to be copied/deleted too.  This is exactly what my app does at
the moment, but in middleware.

Does that "authz" document represent what you are calling a "security
object"?

Regards,

Brian.

Re: Initial couchdb accounts feedback

Posted by cinnebar <cc...@gmail.com>.
Im going to need more time to look at it
i suspect we validate against a"'cat" field which effectively means that
user is a type of namespaced role and other roles are also values keyed by
"cat".

in the long run we intend to add more stuff to this db

we considered naming the db "auth" but we decided to use something like auth
to define the process rather than the data it uses here


cheers

On Mon, Jan 11, 2010 at 5:37 AM, Chris Anderson <jc...@apache.org> wrote:

> On Sun, Jan 10, 2010 at 10:30 AM, cinnebar <cc...@gmail.com> wrote:
> >>
> >> you can override the db name by setting
> >>
> >> [couch_httpd_auth]
> >> authentication_db = usr
> >>
> >> in your local.ini
> >>
> >>
> > this is good :)
> >
> >
> >> overriding "roles" would involve a nasty code change. I don't think
> >> it's worth it.
> >>
> >>
> > hmm...not so good...it breaks an important pattern for us
> >
> >
> > right now the only documents allowed are of type "user". I originally
> >> had it set to be more open, but I think it's better to treat this db
> >> more strictly.
> >>
> >
> > it seems to be an unneccessy property then?
> >
>
> Nope. The deal is we have a strict validation function that validates
> user docs. we also check to make sure a doc is a user doc when you log
> in. putting the type on there means it's something about the doc we
> check (not where we found the doc) that proves it's valid. This means
> in the long run we can add more stuff to this db.
>
> If I was gonna name the db from scratch I might name it "auth".
>
> Chris
>
>
>
>
>
> --
> Chris Anderson
> http://jchrisa.net
> http://couch.io
>

Re: Initial couchdb accounts feedback

Posted by Chris Anderson <jc...@apache.org>.
On Sun, Jan 10, 2010 at 10:30 AM, cinnebar <cc...@gmail.com> wrote:
>>
>> you can override the db name by setting
>>
>> [couch_httpd_auth]
>> authentication_db = usr
>>
>> in your local.ini
>>
>>
> this is good :)
>
>
>> overriding "roles" would involve a nasty code change. I don't think
>> it's worth it.
>>
>>
> hmm...not so good...it breaks an important pattern for us
>
>
> right now the only documents allowed are of type "user". I originally
>> had it set to be more open, but I think it's better to treat this db
>> more strictly.
>>
>
> it seems to be an unneccessy property then?
>

Nope. The deal is we have a strict validation function that validates
user docs. we also check to make sure a doc is a user doc when you log
in. putting the type on there means it's something about the doc we
check (not where we found the doc) that proves it's valid. This means
in the long run we can add more stuff to this db.

If I was gonna name the db from scratch I might name it "auth".

Chris





-- 
Chris Anderson
http://jchrisa.net
http://couch.io

Re: Initial couchdb accounts feedback

Posted by cinnebar <cc...@gmail.com>.
>
> you can override the db name by setting
>
> [couch_httpd_auth]
> authentication_db = usr
>
> in your local.ini
>
>
this is good :)


> overriding "roles" would involve a nasty code change. I don't think
> it's worth it.
>
>
hmm...not so good...it breaks an important pattern for us


right now the only documents allowed are of type "user". I originally
> had it set to be more open, but I think it's better to treat this db
> more strictly.
>

it seems to be an unneccessy property then?

cheers

Re: Initial couchdb accounts feedback

Posted by Chris Anderson <jc...@apache.org>.
On Sat, Jan 9, 2010 at 10:54 PM, cinnebar <cc...@gmail.com> wrote:
> big thanks to chris for the improvements to the security
>
> is there only the single ref to the default account db name in the src?
> and how easy would it be to override the default?

Don't worry, there is no default account name in the source. CouchDB
ships in Admin Party mode before a server admin is configured, so all
clients have admin privileges. This is fine when HTTP access is
restricted to trusted users.

If you're putting your Couch in public all you've got to do is setup
an admin user.

This also means you'll need to give a user account to your http
libraries. They can still use basic auth.

>
> i dont follow the logic for using '_users'.

the worry is that someone will have an in-house 'users' db. With _ we
don't collide with anyone.

>
> so id suggest to default users db name to 'usr'  for a few good reasons and
> id put most weight on  _ and e and pluralize are fluff

dgg cl ll try t

>
> a lot of people like fluff I really dont understand it.
> for me it hurts to hear "i am not an animal i am a javascript function name"
> over and over when sifting through libs
> and then theres impulse to scream in japanese accent "tetsuo !!" whenever i
> accidentlally look at a bit of java.

"i am not an animal i am a javascript function name"

I feel your pain.

>
> i could go on about why three letter names for core keys/names are serious
> good and a bunch of other reasons why we are using 'usr' here...
> but id say i am in a minority on this point so if the default for the name
> of the users db is easy to override then no sweat really i guess...

you can override the db name by setting

[couch_httpd_auth]
authentication_db = usr

in your local.ini

>
> also id like to know if there is a way to overide 'roles', i havent had a
> look at the code, we are using 'cat' (as in category) and its a convention
> across all the documents in out datastores... in our 'usr' docs the "cat"
> key does the same thing as "roles" does in chris's screencast and in other
> docsets it keys to values that are roughly equivalent to the way i have seen
> other couchdb users using "type" basically because it seems a bit confusing
> for example to say the couchdb is duck typed then go and map a docset by
> "type" and "cat" is a bit shorter...

overriding "roles" would involve a nasty code change. I don't think
it's worth it.

>
> in the screencast the "type" key had a "user" value.  is "type" hard coded
> in the users db and if it is what are the other possible values?
>

right now the only documents allowed are of type "user". I originally
had it set to be more open, but I think it's better to treat this db
more strictly.

>
> cheers
>
>
>
> On Sun, Jan 10, 2010 at 2:09 PM, Chris Anderson <jc...@apache.org> wrote:
>
>> On Sat, Jan 9, 2010 at 1:19 PM, David Goodlad <da...@goodlad.ca> wrote:
>> > On Sun, Jan 10, 2010 at 6:22 AM, Matteo Caprari
>> > <ma...@gmail.com> wrote:
>> >> I agree that per-instance-sessions are nice and have cool
>> >> implications, but it means that if I want to run
>> >> applications that don't share users, I have to fire up two couchdb
>> >> instances. This is not a bad thing, just probably not
>> >> very convenient with the current init scripts.
>> >
>> > I had a bit of a think about this overnight (since I'll be running in
>> > this scenario). If there are dbs that shouldn't share users, perhaps
>> > you could prefix the role with the appname. ie: { roles:
>> > ["myapp1:editor"] }. Then once there are reader ACLs, you could test
>> > that the user included roles with the appropriate prefix.
>> >
>>
>> There's something Damien suggested that I think answers this problem
>> and some of those Brian Candler raised.
>>
>> Currently the validation function takes 3 arguments (newDoc, diskDoc,
>> userCtx)
>>
>> The plan is to add a 4th argument, which is a security object. It
>> would be per-app, and could allow a site (I'm thinking an office or
>> some other organization) to map from site-roles to app-roles. So in
>> the case of a hospital, you'd set up a mapping between various site
>> roles like R.N., M.D., orderly, etc, and application roles
>> (prescription-writer, prescription-filler, etc in the prescription
>> app.)
>>
>> I'm not sure if this gets us 100% of the way there, but I think it
>> gets us at least 80%, without being too complicated.
>>
>> Chris
>>
>> > Now that I've given some more thought to this problem, I've come to
>> > the conclusion that if I implement my roles properly reader ACLs can
>> > handle every case that I've been able to come up with.
>> >
>> > Dave
>> >
>>
>>
>>
>> --
>> Chris Anderson
>> http://jchrisa.net
>> http://couch.io
>>
>



-- 
Chris Anderson
http://jchrisa.net
http://couch.io

Re: Initial couchdb accounts feedback

Posted by Noah Slater <ns...@tumbolia.org>.
On 10 Jan 2010, at 16:13, cinnebar wrote:

> valid point but in the context 'usr' is readable and unique

'usr' is typically from UNIX filesystem hierarchy, which is a horrendous mess, and largely opaque to anyone who's not studied it.  I quite like using full english names where that doesn't mean wasting too much space. As for being unique, sure, but so are the alternatives.

Re: Initial couchdb accounts feedback

Posted by Andrew Melo <an...@gmail.com>.
On Sun, Jan 10, 2010 at 10:26 AM, Simon Metson
<si...@googlemail.com> wrote:
> Hey,
>        _usr or _user would seem to make sense to me, since the _ is reserved
> namespace in couchdb (e.g. _id and _rev).
> Cheers
> Simon
>

Yeah, "magic" fields should have a leading underscore to show they are
in the reserved namespace, but let's not drop the 'e' in user, it's
not the 60's anymore, we don't need to sacrifice readability to gain
an extra byte.

best,
Melo

> On 10 Jan 2010, at 16:13, cinnebar wrote:
>
>> valid point but in the context 'usr' is readable and unique
>>
>>
>> On Mon, Jan 11, 2010 at 3:06 AM, Noah Slater <ns...@tumbolia.org> wrote:
>>
>>>
>>> On 10 Jan 2010, at 06:54, cinnebar wrote:
>>>
>>>> so id suggest to default users db name to 'usr'  for a few good reasons
>>>
>>> and
>>>>
>>>> id put most weight on  _ and e and pluralize are fluff
>>>>
>>>> a lot of people like fluff I really dont understand it.
>>>
>>> one mns flff is nthr mns readabil
>>>
>>>
>
>



-- 
--
Andrew Melo

Re: Initial couchdb accounts feedback

Posted by Simon Metson <si...@googlemail.com>.
Hey,
	_usr or _user would seem to make sense to me, since the _ is reserved  
namespace in couchdb (e.g. _id and _rev).
Cheers
Simon

On 10 Jan 2010, at 16:13, cinnebar wrote:

> valid point but in the context 'usr' is readable and unique
>
>
> On Mon, Jan 11, 2010 at 3:06 AM, Noah Slater <ns...@tumbolia.org>  
> wrote:
>
>>
>> On 10 Jan 2010, at 06:54, cinnebar wrote:
>>
>>> so id suggest to default users db name to 'usr'  for a few good  
>>> reasons
>> and
>>> id put most weight on  _ and e and pluralize are fluff
>>>
>>> a lot of people like fluff I really dont understand it.
>>
>> one mns flff is nthr mns readabil
>>
>>


Re: Initial couchdb accounts feedback

Posted by cinnebar <cc...@gmail.com>.
valid point but in the context 'usr' is readable and unique


On Mon, Jan 11, 2010 at 3:06 AM, Noah Slater <ns...@tumbolia.org> wrote:

>
> On 10 Jan 2010, at 06:54, cinnebar wrote:
>
> > so id suggest to default users db name to 'usr'  for a few good reasons
> and
> > id put most weight on  _ and e and pluralize are fluff
> >
> > a lot of people like fluff I really dont understand it.
>
> one mns flff is nthr mns readabil
>
>

Re: Initial couchdb accounts feedback

Posted by Noah Slater <ns...@tumbolia.org>.
On 10 Jan 2010, at 06:54, cinnebar wrote:

> so id suggest to default users db name to 'usr'  for a few good reasons and
> id put most weight on  _ and e and pluralize are fluff
> 
> a lot of people like fluff I really dont understand it.

one mns flff is nthr mns readabil


Re: Initial couchdb accounts feedback

Posted by cinnebar <cc...@gmail.com>.
big thanks to chris for the improvements to the security

is there only the single ref to the default account db name in the src?
and how easy would it be to override the default?
our code base is set for 'usr' and would it be not so fun to have to adjust
the erlang there on every couchdb release

i dont follow the logic for using '_users'.

so id suggest to default users db name to 'usr'  for a few good reasons and
id put most weight on  _ and e and pluralize are fluff

a lot of people like fluff I really dont understand it.
for me it hurts to hear "i am not an animal i am a javascript function name"
over and over when sifting through libs
and then theres impulse to scream in japanese accent "tetsuo !!" whenever i
accidentlally look at a bit of java.

i could go on about why three letter names for core keys/names are serious
good and a bunch of other reasons why we are using 'usr' here...
but id say i am in a minority on this point so if the default for the name
of the users db is easy to override then no sweat really i guess...

also id like to know if there is a way to overide 'roles', i havent had a
look at the code, we are using 'cat' (as in category) and its a convention
across all the documents in out datastores... in our 'usr' docs the "cat"
key does the same thing as "roles" does in chris's screencast and in other
docsets it keys to values that are roughly equivalent to the way i have seen
other couchdb users using "type" basically because it seems a bit confusing
for example to say the couchdb is duck typed then go and map a docset by
"type" and "cat" is a bit shorter...

in the screencast the "type" key had a "user" value.  is "type" hard coded
in the users db and if it is what are the other possible values?


cheers



On Sun, Jan 10, 2010 at 2:09 PM, Chris Anderson <jc...@apache.org> wrote:

> On Sat, Jan 9, 2010 at 1:19 PM, David Goodlad <da...@goodlad.ca> wrote:
> > On Sun, Jan 10, 2010 at 6:22 AM, Matteo Caprari
> > <ma...@gmail.com> wrote:
> >> I agree that per-instance-sessions are nice and have cool
> >> implications, but it means that if I want to run
> >> applications that don't share users, I have to fire up two couchdb
> >> instances. This is not a bad thing, just probably not
> >> very convenient with the current init scripts.
> >
> > I had a bit of a think about this overnight (since I'll be running in
> > this scenario). If there are dbs that shouldn't share users, perhaps
> > you could prefix the role with the appname. ie: { roles:
> > ["myapp1:editor"] }. Then once there are reader ACLs, you could test
> > that the user included roles with the appropriate prefix.
> >
>
> There's something Damien suggested that I think answers this problem
> and some of those Brian Candler raised.
>
> Currently the validation function takes 3 arguments (newDoc, diskDoc,
> userCtx)
>
> The plan is to add a 4th argument, which is a security object. It
> would be per-app, and could allow a site (I'm thinking an office or
> some other organization) to map from site-roles to app-roles. So in
> the case of a hospital, you'd set up a mapping between various site
> roles like R.N., M.D., orderly, etc, and application roles
> (prescription-writer, prescription-filler, etc in the prescription
> app.)
>
> I'm not sure if this gets us 100% of the way there, but I think it
> gets us at least 80%, without being too complicated.
>
> Chris
>
> > Now that I've given some more thought to this problem, I've come to
> > the conclusion that if I implement my roles properly reader ACLs can
> > handle every case that I've been able to come up with.
> >
> > Dave
> >
>
>
>
> --
> Chris Anderson
> http://jchrisa.net
> http://couch.io
>

Re: Initial couchdb accounts feedback

Posted by Chris Anderson <jc...@apache.org>.
On Sat, Jan 9, 2010 at 1:19 PM, David Goodlad <da...@goodlad.ca> wrote:
> On Sun, Jan 10, 2010 at 6:22 AM, Matteo Caprari
> <ma...@gmail.com> wrote:
>> I agree that per-instance-sessions are nice and have cool
>> implications, but it means that if I want to run
>> applications that don't share users, I have to fire up two couchdb
>> instances. This is not a bad thing, just probably not
>> very convenient with the current init scripts.
>
> I had a bit of a think about this overnight (since I'll be running in
> this scenario). If there are dbs that shouldn't share users, perhaps
> you could prefix the role with the appname. ie: { roles:
> ["myapp1:editor"] }. Then once there are reader ACLs, you could test
> that the user included roles with the appropriate prefix.
>

There's something Damien suggested that I think answers this problem
and some of those Brian Candler raised.

Currently the validation function takes 3 arguments (newDoc, diskDoc, userCtx)

The plan is to add a 4th argument, which is a security object. It
would be per-app, and could allow a site (I'm thinking an office or
some other organization) to map from site-roles to app-roles. So in
the case of a hospital, you'd set up a mapping between various site
roles like R.N., M.D., orderly, etc, and application roles
(prescription-writer, prescription-filler, etc in the prescription
app.)

I'm not sure if this gets us 100% of the way there, but I think it
gets us at least 80%, without being too complicated.

Chris

> Now that I've given some more thought to this problem, I've come to
> the conclusion that if I implement my roles properly reader ACLs can
> handle every case that I've been able to come up with.
>
> Dave
>



-- 
Chris Anderson
http://jchrisa.net
http://couch.io

Re: Initial couchdb accounts feedback

Posted by David Goodlad <da...@goodlad.ca>.
On Sun, Jan 10, 2010 at 6:22 AM, Matteo Caprari
<ma...@gmail.com> wrote:
> I agree that per-instance-sessions are nice and have cool
> implications, but it means that if I want to run
> applications that don't share users, I have to fire up two couchdb
> instances. This is not a bad thing, just probably not
> very convenient with the current init scripts.

I had a bit of a think about this overnight (since I'll be running in
this scenario). If there are dbs that shouldn't share users, perhaps
you could prefix the role with the appname. ie: { roles:
["myapp1:editor"] }. Then once there are reader ACLs, you could test
that the user included roles with the appropriate prefix.

Now that I've given some more thought to this problem, I've come to
the conclusion that if I implement my roles properly reader ACLs can
handle every case that I've been able to come up with.

Dave

Re: Initial couchdb accounts feedback

Posted by Matteo Caprari <ma...@gmail.com>.
Hi.

i think _users is a good choice:
underscore is fairly established as "pretend private" marker, and it's
easy to recognise it
as couchdb-ish because it'used already for _utils, _view, etc. (It
also true that _utils is not a db and users may get confused...)

I'm working on openid authentication handler, but don't hold your breath.

I agree that per-instance-sessions are nice and have cool
implications, but it means that if I want to run
applications that don't share users, I have to fire up two couchdb
instances. This is not a bad thing, just probably not
very convenient with the current init scripts.

-teo

On Sat, Jan 9, 2010 at 6:41 PM, Chris Anderson <jc...@apache.org> wrote:
> On Sat, Jan 9, 2010 at 7:34 AM, Matt Goodall <ma...@gmail.com> wrote:
>> Hi,
>>
>> Just a quick bit of feedback after an initial play with the new accounts
>> stuff. Definitely looks interesting! This is based on a fresh install from
>> trunk (r896989).
>>
>> Oh, I should point out that I've never used couchdb to host any sort of
>> couchapp yet (I use couchdb as a "conventional" store) so I may well be
>> missing the point in a few places.
>>
>
> Thanks for the feedback. It's much appreciated.
>
>>
>> = Bugs =
>>
>> If the 'users' database doesn't exist then the doc for the first admin user
>> (the one who spoils the party) does not get created.
>>
>
> Good catch - I thought this was intermittent and was gonna be a pain
> to fix, but if it's easy to trigger it'll be easy to fix.
>
>> Anyone can delete users' docs (even an admin user's doc). _admin users
>> should be able to delete docs. Unauthenticated users should not. I can't
>> decide if a user should be able to delete their own doc.
>
> Agreed. This is a simple bug that's fixed on my laptop. Once I add a
> test I'll check it in. For now I'll let users delete their own docs.
>
>>
>>
>> = Possible Simple Changes =
>>
>> Perhaps the database could be renamed to "_users" as it's a couchdb-managed
>> database? I imagine it's reasonably likely there are databases called
>> "users" in use already.
>
> Worth looking into. I wanted to avoid using an underscore name, but
> maybe this isn't practical. What do others think?
>
>>
>> The _admin/users view emits the whole doc. Would it make sense to use
>> include_docs=true where necessary and save the map's emitted value for
>> something useful in the future?
>
> That view is left over from earlier code so I'll just delete it altogether.
>
>>
>> Perhaps store admin users in the "users" database with a role of "_admin",
>> and leave local.ini alone? I guess there are some
>> backward-compatibility issues to resolve here.
>
> Keeping them in the config is better. They are more robust there
> (loaded before any db is loaded, not deleted if the db file is
> deleted, etc) also I like it that the admin passwords aren't in the
> users db, it should be more secure that way.
>
> There is a validation that system roles (like _admin) can never be
> stored in the users db. They are always applied by CouchDB based on
> other factors.
>
>>
>>
>> = Other Thoughts =
>>
>> Is the "users" database designed to be replicated?
>
> Yes. But replicated can mean different things depending on the use-case.
>
>> If so, isn't there a real
>> danger of getting a username conflict and exposing another user's personal
>> data in a couchapp?
>
> I think this danger isn't so bad. The main reason is that read-control
> (planned but not yet implemented) will be per-database. So if a user
> can read data from the database as themselves, they don't get special
> read access by logging in as different user.
>
> However, if you have a private db (only jchris can read it) then if a
> user on another node is named jchris, and the 2 nodes are merged,
> there's a problem deciding can read the db.
>
> There's things we can do to prevent username hijacking -- probably the
> most important thing would be to check for conflicts on login, and
> prevent people from logging in if the user doc is in a conflict state.
> This would have to be resolved by an administrator.
>
> Beyond being wary of conflicts, I think the current validation
> function will prevent non-admins from introducing conflicts on user
> documents. If you can't update the document, you can't write a
> conflicting version of it. However, an admin could inadvertently
> introduce conflicts if eg: there was a jchris in accounting and a
> jchris in marketing and the 2 users-dbs were merged.
>
>> Perhaps each user needs a uuid of some sort for
>> couchapps to reference (instead of using the username) so the conflict
>> winner still only gets to see their own data.
>
> The problem is we want the login token to be both memorable and
> unique. I think the best solution is to encourage people to use email
> addresses as login tokens. Maybe the Futon UI + validation function
> should go further toward requiring that. (I'm not that into the idea
> of enforcing the presence of an @ sign in your username, but maybe
> it's worth it...)
>
>>
>> Can't quite decide how useful a single "users" database is. I imagine a user
>> would typically be expected to register with each couchapp?
>
> The plan is that the user is logged into the node, not the db, so that
> CouchApp authors can just take for granted that the user is or isn't
> logged in, and never have to write any session management code
> themselves. If you are jchris when you use the calendar it make sense
> that you'd be jchris when you write a blog entry.
>
>>
>> A user can edit their own doc so I assume that means the design is to allow
>> for extra information in the docs, e.g. the user's real name, email address,
>> etc?
>
> We should discourage app devs from overloading the users documents.
> Instead they should use the user-id to create a document in the app
> db, with user preferences.
>
> I'm not sure if it's a good idea to attempt to enforce these
> constraints in code. Hopefully a few examples of doing it right should
> be enough to get people pointed in the right direction.
>
>> Having that information in a different database to where the user's
>> actual data is stored seems quite limiting, e.g. for view collation to see
>> the user's name and postings. The solution is probably per-database users.
>
> I don't think we want per-database users. Because you only want to
> login / logout of the server. I think we should encourage applications
> to maintain user profiles in their own databases, keyed off the user
> name.
>
> Because all the apps on the node share the same session, you can do
> cool stuff like have a user-profile couchapp, which just handles your
> nickname and avatar icon. Other apps could then use those resources
> when displaying user info.
>
> Probably the closest thing to this setup that people are familiar with
> is Google App Engine. As an app developer, you just get the user info
> from a provided API. Of course we add the notion that apps running on
> the same node can query each others' databases.
>
>>
>> openid support would be cute. :)
>
> We've got oauth support. OpenId would definitely be nice. It'd also
> help with the unique identifiers thing.
>
>>
>>
>> Hope that all makes sense.
>>
>>
>> - Matt
>>
>
> Thanks again for the feedback,
> Chris
>
> --
> Chris Anderson
> http://jchrisa.net
> http://couch.io
>



-- 
:Matteo Caprari
matteo.caprari@gmail.com

Re: Initial couchdb accounts feedback

Posted by Chris Anderson <jc...@apache.org>.
On Sat, Jan 9, 2010 at 7:34 AM, Matt Goodall <ma...@gmail.com> wrote:
> Hi,
>
> Just a quick bit of feedback after an initial play with the new accounts
> stuff. Definitely looks interesting! This is based on a fresh install from
> trunk (r896989).
>
> Oh, I should point out that I've never used couchdb to host any sort of
> couchapp yet (I use couchdb as a "conventional" store) so I may well be
> missing the point in a few places.
>

Thanks for the feedback. It's much appreciated.

>
> = Bugs =
>
> If the 'users' database doesn't exist then the doc for the first admin user
> (the one who spoils the party) does not get created.
>

Good catch - I thought this was intermittent and was gonna be a pain
to fix, but if it's easy to trigger it'll be easy to fix.

> Anyone can delete users' docs (even an admin user's doc). _admin users
> should be able to delete docs. Unauthenticated users should not. I can't
> decide if a user should be able to delete their own doc.

Agreed. This is a simple bug that's fixed on my laptop. Once I add a
test I'll check it in. For now I'll let users delete their own docs.

>
>
> = Possible Simple Changes =
>
> Perhaps the database could be renamed to "_users" as it's a couchdb-managed
> database? I imagine it's reasonably likely there are databases called
> "users" in use already.

Worth looking into. I wanted to avoid using an underscore name, but
maybe this isn't practical. What do others think?

>
> The _admin/users view emits the whole doc. Would it make sense to use
> include_docs=true where necessary and save the map's emitted value for
> something useful in the future?

That view is left over from earlier code so I'll just delete it altogether.

>
> Perhaps store admin users in the "users" database with a role of "_admin",
> and leave local.ini alone? I guess there are some
> backward-compatibility issues to resolve here.

Keeping them in the config is better. They are more robust there
(loaded before any db is loaded, not deleted if the db file is
deleted, etc) also I like it that the admin passwords aren't in the
users db, it should be more secure that way.

There is a validation that system roles (like _admin) can never be
stored in the users db. They are always applied by CouchDB based on
other factors.

>
>
> = Other Thoughts =
>
> Is the "users" database designed to be replicated?

Yes. But replicated can mean different things depending on the use-case.

> If so, isn't there a real
> danger of getting a username conflict and exposing another user's personal
> data in a couchapp?

I think this danger isn't so bad. The main reason is that read-control
(planned but not yet implemented) will be per-database. So if a user
can read data from the database as themselves, they don't get special
read access by logging in as different user.

However, if you have a private db (only jchris can read it) then if a
user on another node is named jchris, and the 2 nodes are merged,
there's a problem deciding can read the db.

There's things we can do to prevent username hijacking -- probably the
most important thing would be to check for conflicts on login, and
prevent people from logging in if the user doc is in a conflict state.
This would have to be resolved by an administrator.

Beyond being wary of conflicts, I think the current validation
function will prevent non-admins from introducing conflicts on user
documents. If you can't update the document, you can't write a
conflicting version of it. However, an admin could inadvertently
introduce conflicts if eg: there was a jchris in accounting and a
jchris in marketing and the 2 users-dbs were merged.

> Perhaps each user needs a uuid of some sort for
> couchapps to reference (instead of using the username) so the conflict
> winner still only gets to see their own data.

The problem is we want the login token to be both memorable and
unique. I think the best solution is to encourage people to use email
addresses as login tokens. Maybe the Futon UI + validation function
should go further toward requiring that. (I'm not that into the idea
of enforcing the presence of an @ sign in your username, but maybe
it's worth it...)

>
> Can't quite decide how useful a single "users" database is. I imagine a user
> would typically be expected to register with each couchapp?

The plan is that the user is logged into the node, not the db, so that
CouchApp authors can just take for granted that the user is or isn't
logged in, and never have to write any session management code
themselves. If you are jchris when you use the calendar it make sense
that you'd be jchris when you write a blog entry.

>
> A user can edit their own doc so I assume that means the design is to allow
> for extra information in the docs, e.g. the user's real name, email address,
> etc?

We should discourage app devs from overloading the users documents.
Instead they should use the user-id to create a document in the app
db, with user preferences.

I'm not sure if it's a good idea to attempt to enforce these
constraints in code. Hopefully a few examples of doing it right should
be enough to get people pointed in the right direction.

> Having that information in a different database to where the user's
> actual data is stored seems quite limiting, e.g. for view collation to see
> the user's name and postings. The solution is probably per-database users.

I don't think we want per-database users. Because you only want to
login / logout of the server. I think we should encourage applications
to maintain user profiles in their own databases, keyed off the user
name.

Because all the apps on the node share the same session, you can do
cool stuff like have a user-profile couchapp, which just handles your
nickname and avatar icon. Other apps could then use those resources
when displaying user info.

Probably the closest thing to this setup that people are familiar with
is Google App Engine. As an app developer, you just get the user info
from a provided API. Of course we add the notion that apps running on
the same node can query each others' databases.

>
> openid support would be cute. :)

We've got oauth support. OpenId would definitely be nice. It'd also
help with the unique identifiers thing.

>
>
> Hope that all makes sense.
>
>
> - Matt
>

Thanks again for the feedback,
Chris

-- 
Chris Anderson
http://jchrisa.net
http://couch.io