Couchdb: Per document read-access security

Created on 31 Jan 2019  路  7Comments  路  Source: apache/couchdb

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.

duplicate

Most helpful comment

@ondra-novak heya, I am working on implementing _access and haven鈥檛 yet been very open about the progress. I鈥檒l update 1524 soonish. I鈥檒l take your issue here as another vote that a feature like this is very needed.

All 7 comments

@ondra-novak I think this is a duplicate of @janl 's _access proposal, see https://github.com/apache/couchdb/issues/1524 and specifically https://lists.apache.org/thread.html/6aa77dd8e5974a3a540758c6902ccb509ab5a2e4802ecf4fd724a5e4@%3Cdev.couchdb.apache.org%3E .

Significant progress has been made on this proposal in just the last few weeks.

Edited to add: I realize your proposal is different, but _access is probably farther along than you realize, and I wouldn't want you to dig deeply into coding this just to have to fight out whose PR lands. I've nudged @janl to see if he can update the list / a GH issue somewhere as to the work he's doing.

Hi, so I read the janl's proposal complete and ... let's say, it is not exactly duplicated. And I can also see the reason, why I couldn't find it, because it is trying to solve a different issue - but looks similar.

Before I started to write to anything to the issue tracker, I tried to find the simplest proposal to implement, because I already know, that time of developers is very expensive. The janl's proposal seems much much difficult to implement (from my point of view, it introduces a new indices, need to rewrite a large part of view generation etc) and I am also worrying about final performance.

Question is whether it is need to hide the document or to hide the content of the document. My proposal just require to hide the content of the document, while the document still can be found and check its existence. The janl's proposal is following a way to a "virtual db". Isn't this a little overkill?

_access keyword is seems similar to my _security keyword (just a name). The original _access doesn't seem to distinguish between user name and role, but this is only difference. I dont see a problem to addapt this form. However I can see much easier to use this keyword or "a rule" to control just output without need to affect many core features of the couchdb.

Just my opinion.

Have nice day

@ondra-novak I have no opinion on the merits of your proposal vs. Jan's. I am only observing that both of your proposals probably can't land at the same time in this project.

I also note that we have a very clear need to replace the db-per-user approach with something more performant, and _access solves that problem (along with the partitioned DB work that has just landed).

If his approach is a superset of your approach, why write something that will be superceded by a more powerful feature?

I obviously don't know anything about your plans or roadmap. I am just using latest version of CouchDB for my project, and trying to solve some issue. I've just tried to suggest something less complicated which could solve my issue.

So if the "_access" feature is being implemented or is already implemented, I cannot say anything against it. So we can close this issue and i am looking forward to seeing that feature in a stable version.

@ondra-novak heya, I am working on implementing _access and haven鈥檛 yet been very open about the progress. I鈥檒l update 1524 soonish. I鈥檒l take your issue here as another vote that a feature like this is very needed.

I know the post is closed, but I'm highly interested in the status of this feature as the "per-user" database model is real NO-GO for my projects.

Updates will be on #1524 when available.

Was this page helpful?
0 / 5 - 0 ratings