Reputation: 502
I recently created a 3 server couchdb 2.1 cluster and was looking into creating some application security. The idea is to have a write-only user that will be given to applications that need to write to the database and a read-only user that will be used by applications that read from the database. Another read-only user will be given to developers to do what developers do. The problem is that I can't find any documentation on doing this. We had this previously on an old 1.6 installation, but that was set up before my time. Any guidance is appreciated.
Upvotes: 0
Views: 839
Reputation: 21
Creating a readonly user is fairly straight forward. You have to create a validate function on the database that only allows certain roles to write to the database. The old stack overflow article is here. CouchDB-wide read-only access rights
Write-only databases are a bit trickier. You have to put a proxy in front of the database that only allows access to the write interfaces and blocks access to read interfaces. I had a project where we accomplished this by putting a proxy in front and pointing it to a rewrite interface on couchdb.
Proxy points to
The design doc looks like
{
"_id": "_design/app",
"rewrites": [
{
"to": "../../_bulk_docs",
"from": "/db/_bulk_docs",
"method": "POST"
},
{
"to": "../../_revs_diff",
"from": "/db/_revs_diff",
"method": "POST"
},
{
"to": "../../_local/*",
"from": "/db/_local/*",
"method": "GET"
},
{
"to": "../../_local/*",
"from": "/db/_local/*",
"method": "POST"
},
{
"to": "../../_local/*",
"from": "/db/_local/*",
"method": "PUT"
},
{
"to": "../../../",
"from": "/",
"method": "GET"
},
{
"to": "../../fakedb",
"from": "/",
"method": "GET"
},
{
"to": "/../../fakedb",
"from": "/db/*",
"method": "GET"
}
]
}
This allowed us to open the minimal interfaces to let pouchdb do a one way sync of data from the client to our server. The last bit we had to add was a workaround for pouchdb that creating errors because it makes a request to
when starting replication. The call isn't really necessary and the workaround was to create a document in the database that returned a similar response.
{
"_id": "fakedb",
"_rev": "1-063ad938e0501105d2f304db16dd4970",
"db_name": "dbname"
}
Upvotes: 1