Introduction to CouchDB with .NET part 22: security continued

Introduction

In the previous post we started discussing the security features of CouchDB. An interesting feature of CouchDB is that by default, in the absence of any registered user, everyone is anonymous and all users have full access to all the parts of the Couch DB server: databases, documents, configuration, replication, everything. This is probably so that newcomers to CouchDB don’t need to spend time on security settings before getting started on its features. So the first step is to create a server administrator who then can create new users to prevent anonymous access to the server. We then created two new users, Peter and Mary, and they were promoted to database administrators to a selected database. They can now administer the database that they were assigned to. They still face various restrictions. E.g. they still cannot perform server admin tasks and they cannot delete the database they are administering.

In this post we’ll continue our discussion of this topic and concentrate on database level read and write access.

The _security endpoint

Before we dive into our main topic let’s see how we can get information about the security settings of a database. The _security endpoint shows the various users and roles defined on a database. The URL for the zipcodes database is the following:

GET http://localhost:5984/zipcodes/_security

It responds with the following:


{“admins”:{“names”:[“peter”,”mary”],”roles”:[]},”members”:{“names”:[],”roles”:[]},”ok”:true}
[/sourececode]

We have Peter and Mary as the DB admins of the zipcodes database.

A couple of new demo users

Let’s leave Peter and Mary like they so that you have them as reference if you need some security examples later on. For the upcoming demos let’s create the following users with our server admin:


{
“_id”: “org.couchdb.user:john”,
“name”: “john”,
“password”: “secret”,
“roles”: [],
“type”: “user”
}

{
“_id”: “org.couchdb.user:serena”,
“name”: “serena”,
“password”: “secret”,
“roles”: [],
“type”: “user”
}

{
“_id”: “org.couchdb.user:ellen”,
“name”: “ellen”,
“password”: “secret”,
“roles”: [],
“type”: “user”
}
[/sourececode]

Database members

Database members have read and write access to a database but they lack the database admin rights. If a database has no database members then all authenticated users can add and modify documents. Even though Peter and Mary have been assigned as DB admins of the zipcodes database they can still freely access the other user databases. Similarly, our new users John and Serena have the same rights.

You can pick any database for the upcoming demos, I’ll use the one called “bands” we created before, it really doesn’t make any difference.

Let’s use our server admin and promote Serena to the database admin and John and Ellen as database members:

Adding database admins and members in Fauxton UI CouchDB

Now log in as Peter. You should see that he has no access to the bands database:

User has no access to a specific database in Fauxton UI CouchDB

If you log on as Serena, John or Ellen you’ll see that all of them have read/write access to the bands database. They can all create new and modify existing documents. However, John and Ellen have no database admin access to the bands database.

Gradual access right reduction

You can probably see a pattern here. CouchDB databases start off being as open as possible. Everyone is a server admin after installation. We then create a server admin which at least protects the CouchDB server from anonymous users. The server admin can create other users. These other users have by default a very wide access to the user databases and documents, although server admin rights are denied to them. Then we can allocate the users as database admins or database members to gradually restrict their access to specific databases.

This is in contrast to popular relational databases where new users have very limited access rights which are then extended to specific databases and actions. In CouchDB it’s the way around: a new user has relatively wide access rights which have to be narrowed down to specific databases and actions.

Read-only users

All database members have read and write access to their assigned database(s). The exception is design documents, Ellen and John won’t be able to add design documents:

User failed to create a new design document due to restrictions Fauxton UI CouchDB

They are, however, allowed to create normal, i.e. non-design documents. Only server admins and database admins who were assigned to a database are allowed to create design documents.

We can remove the write access of a specific user using a validation function in a design document. For a reminder you can read this post. The validation function will be called automatically when a database document is inserted or updated. Our goal is to turn John into a read-only user.

Here’s the design document in the bands database that checks the username of the principal and throws an exception if the username is incorrect. You’ll need to log in as Serena, i.e. the DB admin of the bands database or as the server admin to create the following design document:


{
“_id”: “_design/auth”,
“validate_doc_update”: “function(newDocument, oldDocument, userContext){ if ( userContext.name !== ‘serena’ && userContext.name !== ‘ellen’) throw ({forbidden: ‘You have no write access to this database’});}”
}
[/sourececode]

We simply check the name of the user context. If it is neither serena nor ellen then we throw an exception.

Log in as John and try to add a new document. It should fail:

Testing read only access of user in Fauxton UI CouchDB

John can still read all the documents as expected. It can be cumbersome though having to come back to this design document and add new users that have write access. This type of control is easier to implement using database roles.

We’ll look into database roles in the next post.

You can view all posts related to data storage on this blog here.

Advertisements

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

One Response to Introduction to CouchDB with .NET part 22: security continued

  1. Pingback: CouchDB Weekly News, July 6, 2017 – CouchDB Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

ultimatemindsettoday

A great WordPress.com site

Elliot Balynn's Blog

A directory of wonderful thoughts

Robin Sedlaczek's Blog

Developer on Microsoft Technologies

HarsH ReaLiTy

A Good Blog is Hard to Find

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

the software architecture

thoughts, ideas, diagrams,enterprise code, design pattern , solution designs

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Cyber Matters

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: