CouchDB’s TLS configuration isn’t just about encrypting data in transit; it fundamentally changes how CouchDB authenticates itself to clients and how clients authenticate to CouchDB.
Let’s see CouchDB in action, serving a simple request over TLS.
First, we need a CouchDB instance running and some basic TLS certificates. For local testing, openssl is your friend. We’ll generate a self-signed certificate and key:
openssl req -x509 -newkey rsa:4096 -keyout couchdb.key -out couchdb.crt -days 365 -nodes -subj "/CN=localhost"
This creates couchdb.crt (the certificate) and couchdb.key (the private key).
Next, we tell CouchDB to use these. Edit your local.ini (or default.ini if you’re starting from scratch):
[ssl]
cert_file = /path/to/your/couchdb.crt
key_file = /path/to/your/couchdb.key
Make sure the paths are correct for your system. If your CouchDB instance runs as a different user (e.g., couchdb), that user needs read permissions on these files.
After restarting CouchDB, you can test the connection using curl. Notice the -k flag, which tells curl to ignore certificate validation errors (since we used a self-signed cert):
curl -k https://localhost:5984/
You should get the familiar CouchDB welcome message:
{"couchdb":"Welcome","version":"3.2.1","git_sha":"..."}
If you omit -k, curl will complain about the self-signed certificate, which is the correct behavior in a production scenario.
The core problem CouchDB’s TLS configuration solves is the need for secure communication. Without it, any data sent between your application and CouchDB, including credentials and sensitive information, is transmitted in plain text, vulnerable to eavesdropping. TLS creates an encrypted tunnel, ensuring confidentiality and integrity.
Beyond encryption, TLS enables authentication. When you configure cert_file and key_file, CouchDB presents its certificate to connecting clients. The client (like curl or your application) can then verify that it’s talking to the real CouchDB instance and not an imposter. This is crucial for preventing man-in-the-middle attacks.
The full mental model involves several components:
- Certificates: These are digital documents that bind a public key to an identity (like
localhost). A certificate authority (CA) typically issues them, but self-signed certificates are common for testing or internal networks. - Private Key: This is the secret counterpart to the public key in the certificate. It’s used by the server to prove its identity and decrypt data encrypted with its public key. It must be kept secret.
- CouchDB Configuration (
[ssl]section): This is where you tell CouchDB where to find its certificate and private key. - Client Configuration: Your client (e.g.,
curl, a web browser, an application library) needs to know how to connect to CouchDB usinghttpsand, optionally, how to verify CouchDB’s certificate (or trust a specific CA).
The verify option in CouchDB’s local.ini ([ssl] section) is where things get really interesting for mutual TLS (mTLS). Setting verify = verify_peer or verify = verify_peer_once tells CouchDB to request a certificate from the client. If it does, CouchDB will then check if that client certificate is valid, often by looking up the CA that signed it in a separate ca_certs_file. This is powerful for ensuring only authenticated clients can access your database.
The most surprising thing is how often people get stuck on file permissions. CouchDB runs as a specific system user (often couchdb). If that user cannot read the .crt and .key files, CouchDB will fail to start or simply won’t serve TLS connections, often with cryptic errors that don’t immediately point to file access. You must ensure the CouchDB user has r-- permissions on both the certificate and key files.
The next step is often configuring client-side certificate validation or exploring more advanced mTLS setups.