Using RethinkDB 2.3's user authentication

When you deploy a new RethinkDB deployment or update RethinkDB to version 2.3, you need to know about RethinkDB's new user authentication system. It's a great enhancement to RethinkDB but it does change how you use Compose's RethinkDB deployments.

Flashback

Before 2.3, RethinkDB had no user authentication at all. Clients could validate themselves by presenting an auth key, but that was per server. On Compose we upped our security by ensuring RethinkDB deployments connected over HTTPS connections and had a haproxy portal guarding the gates asking for a username and password.

When you added a user in the Compose UI, it was being added to that haproxy portal. That meant we could deliver SSL/TLS secured connections and control access to the RethinkDB deployment.

RethinkDB 2.3 sees a lot of changes and we've adopted them for our Compose deployments. For example, now your RethinkDB connections now go to a RethinkDB Proxy node because that supports SSL/TLS. From RethinkDB 2.3 onwards, you also administer users with RethinkDB because there's a whole new users, permissions and scopes system in RethinkDB now. That's covered in detail in the documentation.

Quickly Up

If you want to get up and running quickly though, follow this quick guide. RethinkDB now has it's own users table in the rethinkdb database. To add users means you have to connect to the Admin UI of RethinkDB first and for that, you need the admin user. That user is automatically set up for you when you create your deployment. Look on the Compose Console's overview page for your deployment and you'll see this:

Authentication credentials

The Authentication Credential is the password for the admin user. You'll need that to log in to the Admin UI. Click the Show/Change link to reveal it.

If you've read all the documentation at this point, you may wonder why you need a password at all as the docs say that there's no protection for the Web UI. At Compose, we don't like leaving web interfaces unprotected so we made sure your web connection requires the admin authentication credentials to log in.

When you use your web browser to access the Admin UI link shown, do be aware that the site is served with a self-signed certificate and will usually require you to make an exception for that domain. The connection is still encrypted.

Once we're in the Admin UI, we can create a user in the Data Explorer. Select Data Explorer in the top menu bar and go to the editor window and type something like this:

Adding a user

Let's look at command in more detail:

r.db('rethinkdb').

RethinkDB's user table is kept in the rethinkdb database, so we address that database.

r.db('rethinkdb').table('users').

The users table is where the user information is kept.

r.db('rethinkdb').table('users').insert({id:"brian",password:"brianpass"})

And we want to insert an object that will represent our user. It has an id value with a value set to our new user name and a password value set to a super secret password.

This command will create a user with that password. You may wonder "Can I query that table to get the password back?", well, no you can't; the password field comes back as a boolean when you query it. If we run r.db('rethinkdb').table('users') we can see that.

User Query

Permission seeking

That command created a user, but if you connected to the RethinkDB deployment as that user, you'd quickly find you couldn't do anything with it. That's because it has been granted no permissions. RethinkDB's permissions can be global, at the database level or at the table level.

The permissions themselves are kept in another system table. If you run r.db('rethinkdb').table('permissions') on a new RethinkDB deployment you'll get results as pictured.

permissions

As you can see, admin has all four available permissions. The config permission is about being able to configure the system, including adding and removing tables. The connect permission controls whether the user can make an outgoing connection with the http command to retrieve data from the web. The read and write permissions should be self-explanatory.

We don't directly modify this table though. For that we have the grant command. This comment lets us set the permissions for a user on a particular object. So say we have a contents database with a table settle we can give the brian user read and write permissions to that with:

r.db("contents").table("settle").grant("brian",{ read: true, write:true })  

You many want to give brian read and write access to the entire database:

r.db("contents").grant("brian",{ read: true, write:true })  

And, finally, if you want to grant admin level permissions to brian (but not Admin UI login capability) you can do:

r.grant("brian", { read: true, write: true, config: true, connect:  true})  

We do advise you consider your policy for permissions if you do that more than once. You can read more about permissions in the documentation where it goes into more detail on the scoping.

If you just want to quickly get up and running with a client connected using a particular database, your likely best option is:

r.db("dbname").grant("user",{ read: true, write: true, config: true, connect:  true})  

Clients

Clients libraries for RethinkDB have been updated so they take user and password parameters. The user parameter typically defaults to admin while the password defaults to an empty string. Details for the connect paramters for JavaScript, Python, Ruby and Java are in the RethinkDB documentation. For Go, the details also cover programmatic user creation.

Migrating to 2.3.x

The details of the migration process are covered in a the previous RethinkDB 2.3 article. In the process, the old Authkey is turned into the password for the admin account. Use the instructions above to add users.

Step forward

The addition of users, permissions and scopes to RethinkDB enables it to be used in more controlled production environments. It's another big step forward for the RethinkDB database, even if it does introduce the "hassle" of creating and controlling users.