Introduction

CouchDB has a good HTTP API which encourages you to put your client applications in direct contact with your database. However, most dynamic systems require some kind of authentication and authorization. Per database there is the possibility of using Authentication and Authorization. This wiki page tries to summarize the possible solutions to using per document authentication and authorization.

Note: CouchDB has not be designed to support per-document read-control, and such a feature is not on the Roadmap. If you are reading this page, you should probably start thinking about using a database-per-security-group approach. In this model you create a database for a project, and grant only a certain set of users access to read and write to it. Filtered replication can be used to create subsets of a larger database when fine-grained control is needed.

The problem: For a given user, allow only specific access to a given document in the database.

The user is authenticated using any kind of authentication method (HTTP basic auth, or otherwise) and is considered to be identified by a single identifying string. Under the term "specific access", this document considers three types: being able to verify existence, being able to read the document, and being able to update the document (deleting the document is considered an update of the document)

Possible solutions

Database per user

Create one database for each user and use authentication on the database for that given user. Because views do not work across databases, you will have to replicate all needed data between the different user databases to allow for a view to contain both private and public/other users' data. Because normal users can not create/delete databases, you will need to have a separate process running which watches your database for changes and creates a new user database when a new user registers.

Access protection this solution implements:

Update: completely, the database can be protected against other users writing into it.

Verify existence: it is still possible to verify existence of a document because other users are given either complete read possibilities or no read abilities.

Read: It is possible to deny all other users access to the database

Limitations:

Scalability: to support both readable and non-readable documents, you will have to replicate data from on user database to another users' database.

Volume: replicating data per user will probably create way to much data.

Views could still work if readable documents are copied between the different user databases.

Smart proxy

Create a smart proxy that wraps all documents with the user credentials and filters all results. Access protection this solution implements:

Update: completely, the proxy will request the document, inspect the credentials and then allow or deny the update

Verify existence: it is still possible to verify the existence of the document, because trying to do an update will result in an Access denied instead of Not found.

Read: protected by the proxy, which will filter the data out.

Limitations:

Scalability: each CouchDB node will require this kind of smart proxy in front of it.

Speed: having a proxy will increase the request latency.

Views are crippled, if the view depends on the user it will have to be done "live", by the proxy, which completely destroys the benefits of incremental map-reduce.

Document encryption on a per user basis

This solution is described in a google document which was mentioned on the development mailinglist. The goal of this solution is to create a P2P like system, where you can replicate data to nodes which you don't trust.

Access protection this solution implements:

Update: partially, delete is still possible but the encrypted part can not be corrupted.

Verify existence: It is still possible to verify the existence of a document.

Read: protected by the strength of the encryption.

Limitations:

As soon as you have encrypted data on the database end, queries become a problem.

There is often no real-world need to freely distribute encrypted data. Therefore this approach is considered to P2P centric.

Validate_doc_read function

Have a javascript function be called on every read, in the same manner as the validate_doc_update system is applied. A patch has been posted.

Access protection this solution implements:

Update: none, you need validate_doc_update for that

Verify existence: complete if the right error codes are returned

Read: only direct get requests

Limitations:

Performance is probably degraded because you have to execute a Javascript function on every read.