Using Two-Factor Authentication (2FA) in CouchDB posted Wednesday, June 25, 2025 by The Neighbourhoodie Team tipCouchDB
With growing digital security risks it’s becoming increasingly important to implement a secured method of authentication, especially for critical services like database access. The good news is CouchDB supports two factor authentication out-of-the box without any need for extensive configuration.
When enabled, a second factor is required to acquire a session cookie and reject basic authentication attempts (as a second factor cannot be presented).
To enable this, you add a totp
object to your user doc with a secret key
value. Let’s look at the details on how to do this. See below for an example.
What is TOTP
TOTP or time-based one-time password is a form of two factor authentication which generates a 6-8 digit code that is valid for a specified amount of time only for one login session or transaction. Tools like Aegis, 2FAS, Ente, Google Authenticator etc. can be used to generate these codes when a secret key or QR code is added.
Using TOTP in CouchDB
CouchDB uses the _users
database to manage its user account information including information on authentication and authorization. CouchDB stores the TOTP settings per user in this _users
database. When this is set the user must provide a valid time-based token along with their username and password to access the database.
Creating a user with TOTP
To get started you’ll be required to create a randomly generated base32 string. This will be used as the token for setting the TOTP for your user. Here’s an example of how a random key can be generated. /dev/urandom
ensures the string is random.
# Generate random token key
LC_ALL=C tr -dc 'A-Z2-7' </dev/urandom | head -c 32; echo
Use this token to create a user, passing it under totp
and key
properties. This will enable two factor authentication for the user. Note that an admin account will be required to create a user. Here is further documentation on creating users in CouchDB.
curl -X PUT http://admin:password@localhost:5984/_users/org.couchdb.user:USERNAME \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"name": "USERNAME", "password": "PASSWORD", "roles": [], "type": "user", "totp": {"key": "YOURTOKEN"}}
Logging in with password and TOTP
A TOTP app as mentioned above can be used to create tokens for login. To do so, add the key
created in the previous step to your authenticator. This will generate a time bound token
which needs to be used for logging in.
To log in, send a post request to _session
making sure to pass the token
from the authenticator.
curl -X POST http://localhost:5984/_session \
-H "Content-Type: application/json" \
-d '{
"name": "username",
"password": "password",
"token": "123456"
}'
If password and token are both valid CouchDB returns a session cookie that can be used in subsequent requests.
{"ok":true,"name":"ninette2fa","roles":[]}
Tokens generated using the authenticator apps are time bound and generally expire after 30 seconds. When an expired token or wrong password is used, an error message will be displayed.
{"error":"unauthorized","reason":"Name or password is incorrect."}
Saving and using Auth session
The Auth token generated can be saved in a separate .txt
file or echoed to be used later.
curl -c cookie.txt -X POST http://localhost:5984/_session \
-H "Content-Type: application/json" \
-d '{
"name": "username",
"password": "password",
"token": "123456"
}'
The auth session can then be passed with each request. For example to view a document the following curl
command can be run passing the AuthSession
.
# Example passing AuthSession directly
curl -H "Cookie: AuthSession=AUTH_SESSION_COOKIE" http://localhost:5984/DB_NAME/DOC_NAME
# Example using the cookie.txt
curl -b cookie.txt http://localhost:5984/DB_NAME/DOC_NAME
Here are some examples of doing the same requests using fetch()
to save and reuse the cookies session.
fetch()
in browser using credentials: include
// Log in and store the session cookie in the browser
await fetch('http://localhost:5984/_session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include', // Store cookies
body: JSON.stringify({
name: username,
password: 'password',
token: '123456'
})
});
// Use the session cookie to access a protected database document
const res = await fetch('http://localhost:5984/DB_NAME/DOC_NAME, {
credentials: 'include'
});
fetch()
with manual cookie handling
const sessionResponse = await fetch('http://localhost:5984/_session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'username',
password: 'password',
token: '123456'
})
});
const cookie = sessionResponse.headers.get('set-cookie')
// Use the session cookie to access a protected database document
const dataResponse = await fetch('http://localhost:5984/DB_NAME/DOC_NAME', {
headers: {
Cookie: cookie
}
})
Alternatively, secured session handlers like fetch-cookie
or axios
can be set up to reuse session cookies.
// fetch-cookie
import nodeFetch from 'node-fetch'
import fetchCookie from 'fetch-cookie'
const fetch = fetchCookie(nodeFetch)
// Use `fetchCookie` as you would use `fetch`
And that’s it! Setting up 2FA in CouchDB is a straightforward way to add a layer of security, but more importantly, peace of mind.
« Back to the blog post overview