-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Summary
Allow to control, who can retrieve document by declaring security object along with the document
Desired Behaviour
This proposal may look slightly less complex than other proposals I have found in the suggestion box while writing this article. For example #1504. My proposal should be easy to implement and backward compatible.
Default behaviour is remain unchanged. Once the user or its role is listed in members section of the _security, all of the documents of the database can be retrieved without limitation. The change comes with a new reserved key "_security" included into the document
{
"_id":"example",
"_security":{"roles":{...}, "users": {...}},
}
The key _security have exactly the same format as members sections of the security object. You can define roles and users. If there is a match with the current user or its role, the document can be retrieved through the HTTP API to the user. If there is no match, the error object is retrieved instead. The key itself is visible to the readers and can be modified. There can be a VDU function to validate the content of _security field
When the such security is applied? It is applied generally everywhere, where document is prepared for output to the response. It includes: GET, _bulk_get, include_docs, etc... However, it doesn't prevent to read the document by the query server to build views. So document (or some part) still can be retrieved through the view (but not though include_docs)
Design documents
To prevent the user to access the such documents through the design's document functions, the security object is also applied to design documents. In this case, it also prevents unauthorised users to execute functions on the design docs. (excluding VDUs)
{
"_id":"_design/topics",
"_security":{"roles":{...}, "users": {...}},
"views":{...},
"shows":{...}
}
Mango indexes
Mango indexes introduces little challenge to this proposal because, the _find function allows to specify any fields from the document and acts as include_docs with filtering. Applying the above proposal can cause, that _find will be forced to filter out the inaccessible documents from the result
This has a several impact to usefulness of the mango queries. So my proposal suggest to extend _security for the _index definition
{
"index": {
"fields": ["foo"]
},
"name" : "foo-index",
"type" : "json",
"_security": {
"roles":["reader"],
"fields":["_id","_rev","bar","baz"]
}
}
So the index definition above makes index available only to users with the role "reader". They will be able to retrieve "_id","_rev","bar" and "baz" fields from the documents that fails to security check otherwise for that users. Accessing the other fields causes that these documents will be filtered out of the result.
Replication
Replication is executed under a specified user context and all the above rules are also applied. If the replication doesn't have access to a document, the document is not replicated.
Possible Solution
- check and apply _security key when document is serialised to the output
- check and apply _security key while execution function in a design document (exclude VDU functions)
- check and apply _security key while searching for the index
- implement field filtering for _index and _find
Additional context
Currently, the database is open to everyone who has a role in members section. It is hard to hide some documents to some users, There is only solution to use two or more databases while indexing these databases can be difficult. CouchDB has also one special database, where only owner of the document can retrieve its content - _users - but this behaviour is hard-coded and can't be implemented otherwise. By introducing per-document security this hard-coded behaviour is no longer needed.
Related issues #1558, #1724, #1504
PS: Sorry for any weird wording and mistakes in my English. I hope that everything is understandable.