Configure Auth0 JWT on CouchDB

Published on

CouchDB is an OpenSource NoSQL document database developed by Apache; it has built-in data replication which makes it great for offline-first applications.

Data replication allows users to continue using your application with a local copy of the database while offline โ€” then once they are back online; their changes are automatically replicated (synchronized) with the remote database.

To replicate data securely users need to be authenticated on the remote CouchDB server. There are a few ways to do this;

  • Creating a user in the _users authentication database and using Basic Authentication or Cookies with each request
  • Using an extenal JSON Web Token (JWT)

Using external JWT tokens on CouchDB

You can use any JWT provider; in this example I will be using Auth0.

Firstly you need to have the following prerequisites;

  • An account on Auth0
  • An application on Auth0. See Quickstart guides for examples on how to create one.

After creating your application on Auth0 you should have a JSON Web Key Set url similar to this one

https://your-domain.auth0.com/.well-known/jwks.json

To find this on Auth0; navigate to the Advanced Settings section on your app and select the Endpoints tab.

Enable JWT authentication on CouchDB

Log into your CouchDB instance using Fauxton or REST API and enable JWT authentication by adding {chttpd_auth, jwt_authentication_handler} to authentication handlers

Set up public keys on CouchDB

Then add your public keys to the jwt_keys section of the configuration

[jwt_keys]
rsa:YOUR_KEY_ID = -----BEGIN PUBLIC KEY-----\n<YOUR_PUBLIC_KEY_FROM_JWK_SET>\n-----END PUBLIC KEY-----\n

Get the PEM format of your public key from the JWT key set url with the curl and openssl commands

curl https://your-domain.auth0.com/pem -s | openssl x509 -pubkey -noout

Get the key IDs from the JWT key set url using the kid value

{
    keys: [
        {
            kid: KEY_ID
        }
    ]
}

Your changes should be applied and you can make requests with a Bearer {jwt_token} in the Authorization header. You may need to restart your CouchDB server if you made the changes locally to the default.ini or local.ini files.

curl  -H "Authorization: Bearer AUTH0_JWT_TOKEN" https://your-couchdb-server/_session

If everything went well you should get a response like this

{"ok":true,"userCtx":{"name": USER_ID,"roles":[]},"info":{"authentication_handlers":["cookie","jwt","default"]}}

Authorizing access to a database

Since we may have multiple databases in our CouchDB instance we would want only authorized users have access to a database.

In CouchDB you can get authorized into either a member or admin class. To authorize a user add the USER_ID to either the member or admin fields. Alternatively you can define roles in your JWT provider and use those instead of individually adding usernames.

For Auth0, refer to the user_id field in the user details tab under Indetity provider attributes.

You should be able to make a request to the database and get a successful response

curl  -H "Authorization: Bearer AUTH0_JWT_TOKEN" https://your-couchdb-server/your-database/

Thatโ€™s all for now.