Closed gr2m closed 8 years ago
Sounds good to me. How do we start?
I talked to @jan because it’s not yet clear on how we plan to build this without compromising security. The major concern is that if we decide to move the authorisation layer to api, and we make a slight mistake in our implementation, the door is open for data leaks. And we must eliminate that possibility.
I think we can account for that by adding another requirement: we don’t replace the CouchDB auth / security features, we add an additional layer to Node. So even if we do something wrong in our Node layer, CouchDB will error based on user & database _security settings, as it is today.
That will of course only work if CouchDB is used as Hoodie’s back-end, it will not help us with Cloudant. So I don’t mind leaving the Cloudant compatibility out of scope for this discussion. The benefits still outweigh the costs
As a user of a Todo app
Below I show the requests the differences in the requests that Hoodie sends to CouchDB behind the curtain of Hoodie’s REST API
PUT /_users/org.couchdb.users:pat
POST /_session
PUT /_users/org.couchdb.users:pat
With the new setup, we still persist user accounts in /_users, so the part is the same. Hoodie will pick up the new account, confirm it by adding roles [“id:abc4567”, “db:abc4567:read”, “db:abc4567:write”]
, just like Hoodie is working now. And it creates the “user-abc4567” database with the /_security
and the /_design/permissions
just like before.
There is no POST /_session
because we calculate the session ID exactly the same way that CouchDB would do it, only in the node layer, based on CouchDB secret, session timeout, password hash & salt.
So now we can respond to a sign in request, without talking to CouchDB, and we can tell if a session is valid. But just in case something goes wrong in the node layer, we will still always send the AuthSession Cookie towards CouchDB as it is today, and CouchDB remains as our security layer for all requests against databases.
Todo gets created locally, and then pushed to Hoodie using the sync APIs.
POST /user-abc4567/_bulk_docs
Cookie: AuthSession=….
POST /user-abc4567/_bulk_docs
Cookie: AuthSession=….
There is no difference if the user has a valid session. We can proxy trough all requests if we want.
We could fail early because api knows if the user has a valid session and if the user is authorised, but we can leave that out of scope for now, to keep things simpler.
POST /_session
no request to CouchDB
Just as in step 1, we calculate the session id in node the same way it would be calculated in CouchDB.
After sign in, the user pulls changes from the database belonging to the user
POST /user-abc4567/_bulk_docs
Cookie: AuthSession=….
POST /user-abc4567/_bulk_docs
Cookie: AuthSession=….
There is no difference if the user has a valid session. We can proxy trough all requests if we want.
We could fail early because api knows if the user has a valid session and if the user is authorised, but we can leave that out of scope for now, to keep things simpler.
:+1: for the thoughtful consideration on security
This might be relevant: https://github.com/pouchdb/express-pouchdb/issues/271 @boennemann @christophwitzko.
this is done in new hoodie
Goal
Remove dependency on CouchDB’s built-in authorization system (
/_session
requests,_users
database,db/_security
settings).Motivation
How to
We think that we can move the auth logic to Node without loosing compatibility with CouchDB.
For example, user accounts could be stored in any database and we would calculate salt & password hashes just as CouchDB does. If the database is
_users
though, then we would store the user accounts just as CouchDB expects them, so a user account created with Hoodie can be used to sign in to the CouchDB directly, if needed.We would manage read/write access to databases by adding according roles to the accounts, e.g.
"db:namehere:read"
.And for CouchDB and others that support it, we set the
_security
on created databases to something likeand add the design doc similar to what we do right now:
By following the roles conventions, we only need to know the account roles to determine if a user is allowed to read / write to a certain database, which will reduce the interaction with CouchDB to a minimium.
Next steps