fix(ferretdb): create the Mongo user via DocumentDB to fix SCRAM salt length

A plain CREATE ROLE ... PASSWORD stores PostgreSQL's native 16-byte SCRAM salt.
DocumentDB has no check_password_hook, so that salt is served verbatim to Mongo
clients, which reject it at SASL step2 with 'invalid salt length of 16'.

Provision the user through documentdb_api.create_user / update_user instead:
DocumentDB builds the SCRAM-SHA-256 verifier with documentdb.scramDefaultSaltLen
(28 bytes) via its own scram_build_secret. create_user only accepts a read-only
role or the clusterAdmin + readWriteAnyDatabase pair, so use the latter for R/W.

- CREATE EXTENSION documentdb now runs before user provisioning so the API
  functions exist.
- Spec built with jq (password JSON-escaped) and passed in a $DDB$ dollar-quoted
  SQL literal; idempotent via update_user when the role already exists.
- Set password_encryption = 'scram-sha-256' explicitly in postgresql.conf.
This commit is contained in:
Damien
2026-05-29 11:18:28 +02:00
parent f13af26a62
commit d10efadaba
2 changed files with 34 additions and 16 deletions

View File

@@ -142,7 +142,7 @@ PostgreSQL role, and the data are left untouched.
- **OS**: latest Debian LXC template (auto-detected), unprivileged, `nesting=1`, `/dev/net/tun` passthrough for Tailscale
- **Storage engine**: PostgreSQL `17` (PGDG) + the DocumentDB extension (`pg_documentdb`, `pg_cron`), loopback-only on `127.0.0.1:5432`
- **Proxy**: official `ferretdb` deb from `github.com/FerretDB/FerretDB`, systemd unit, listening on `0.0.0.0:27017`
- **Auth**: MongoDB client credentials map to PostgreSQL roles; the app role is a superuser so the single homelab user can manage collections and Mongo users (`documentdb.enableUserCrud`)
- **Auth**: the app user is provisioned through `documentdb_api.create_user` (roles `clusterAdmin` + `readWriteAnyDatabase`), **not** a plain `CREATE ROLE`. DocumentDB builds the SCRAM-SHA-256 verifier with its own 28-byte salt (`documentdb.scramDefaultSaltLen`); a native PostgreSQL role would store a 16-byte salt that MongoDB clients reject (`invalid salt length of 16 in sasl step2`). FerretDB connects to PostgreSQL as the same user.
- **Network**: FerretDB exposed on `0.0.0.0:27017`; Tailscale runs in the LXC for tailnet reachability (no `serve`)
- **Config**: `/etc/postgresql/17/main/conf.d/documentdb.conf` (extension settings) and `/etc/systemd/system/ferretdb.service.d/override.conf` (`FERRETDB_POSTGRESQL_URL`, `FERRETDB_LISTEN_ADDR`)
- **Logs**: PostgreSQL via its stock `logrotate`; FerretDB via journald, capped at `SystemMaxUse=200M`