incubator-couchdb-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Brian Candler <B.Cand...@pobox.com>
Subject Re: Initial couchdb accounts feedback
Date Sat, 09 Jan 2010 22:17:34 GMT
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.

Mime
View raw message