fix(auth): front CouchDB with nginx to mark AuthSession cookie Secure

CouchDB 3.5 derives the Set-Cookie Secure flag from the raw mochiweb
socket scheme and ignores X-Forwarded-Proto/Ssl for cookie attribution.
Behind a TLS-terminating proxy the cookie was emitted without Secure,
so browsers dropped the SameSite=None AuthSession cookie on cross-origin
requests — POST /_session returned 200 but the next GET /_session showed
userCtx.name: null and PouchDB stayed unauthenticated.

Add an nginx sidecar that adds Secure via proxy_cookie_flags, route the
public domain through it, and make couchdb internal. Also persist
same_site=none in couchdb-init so the setting survives container
recreation (local.d/ is not in the data volume).
This commit is contained in:
Julien Calixte
2026-06-02 22:05:47 +02:00
parent c3c75787f4
commit 2aa10b1711
3 changed files with 83 additions and 8 deletions

View File

@@ -3,7 +3,6 @@ services:
image: couchdb:3
restart: unless-stopped
environment:
SERVICE_FQDN_COUCHDB_5984:
COUCHDB_USER: ${COUCHDB_USER:-admin}
COUCHDB_PASSWORD: ${COUCHDB_PASSWORD}
expose:
@@ -12,6 +11,24 @@ services:
- couchdb_data:/opt/couchdb/data
networks:
- default
# nginx fronts CouchDB to add `Secure` to the AuthSession cookie. CouchDB only
# marks the cookie Secure when mochiweb sees a true HTTPS socket, which never
# happens behind a TLS-terminating proxy — so SameSite=None cookies would be
# dropped by browsers on cross-origin requests. See nginx/default.conf.
nginx:
image: nginx:alpine
restart: unless-stopped
depends_on:
- couchdb
environment:
SERVICE_FQDN_NGINX_5984:
expose:
- "5984"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
networks:
- default
- coolify
labels:
- "traefik.enable=true"
@@ -59,11 +76,15 @@ services:
"$$base/_node/_local/_config/$$1/$$2" -d "\"$$3\"" >/dev/null
echo "cfg $$1/$$2 = $$3"
}
put_config chttpd enable_cors true
put_config cors origins 'http://localhost:8080,http://localhost:5173,http://localhost:3000,http://localhost:4173,https://vaquant.at'
put_config cors credentials true
put_config cors methods 'GET, PUT, POST, HEAD, DELETE'
put_config cors headers 'accept, authorization, content-type, origin, referer, x-csrf-token'
put_config chttpd enable_cors true
put_config cors origins 'http://localhost:8080,http://localhost:5173,http://localhost:3000,http://localhost:4173,https://vaquant.at'
put_config cors credentials true
put_config cors methods 'GET, PUT, POST, HEAD, DELETE'
put_config cors headers 'accept, authorization, content-type, origin, referer, x-csrf-token'
# SameSite=None is required for PouchDB cross-origin cookie sessions.
# Browsers also require Secure on SameSite=None cookies — that flag is
# added by the nginx sidecar via proxy_cookie_flags.
put_config couch_httpd_auth same_site none
signup:
build: