Summary
With the default auth configuration (AuthMode::Trust, the built-in default from nodedb/src/config/auth.rs:200), any pgwire client can authenticate as any username — including usernames that were never created via CREATE USER — with any password (including empty). Declared user passwords (CREATE USER alice WITH PASSWORD 'x') are silently ignored in Trust mode. docs/security/auth.md doesn't mention Trust mode exists.
Environment
- NodeDB v0.0.2,
nodedb-0.0.2-linux-arm64 release binary
- Running in OrbStack Ubuntu ARM64 VM, pgwire on
127.0.0.1:6432
- Source HEAD for analysis:
b024c560
- No
nodedb.toml configured — using built-in defaults
- Client:
postgres.js via Bun
Reproduction
import postgres from 'postgres';
async function tryConnect(user: string, pw: string) {
const s = postgres({ host: '127.0.0.1', port: 6432, user, password: pw,
database: 'moomoori', prepare: false, fetch_types: false, max: 1 });
const r = await s.unsafe('SELECT 1 AS x');
console.log(user, pw, '->', r);
await s.end();
}
// user was created with: CREATE USER alice WITH PASSWORD 'strong_real_pw_123' ROLE readwrite TENANT 1
await tryConnect('alice', 'strong_real_pw_123'); // accepted (expected)
await tryConnect('alice', 'wrong_password'); // accepted (unexpected)
await tryConnect('alice', ''); // accepted (unexpected)
await tryConnect('nosuchuser_ever_created', 'anything'); // accepted (unexpected)
All four connections succeed and return [{ x: 1 }].
Expected
At minimum, Trust mode should still verify the connecting username corresponds to a known user (matches PostgreSQL's trust method behavior — it skips password verification but still resolves the role from pg_roles). Right now any fabricated username is accepted and presumably operates under some default identity.
Ideally also:
docs/security/auth.md documents that Trust is the default and what it means
- Or the default shifts to a mode that requires existence (SCRAM with a mandatory
NODEDB_SUPERUSER_PASSWORD env var on first boot, etc.)
Actual
- Non-existent usernames authenticate successfully.
- Any password (including empty) authenticates successfully for existing users.
- Declared
WITH PASSWORD '...' is dead metadata under Trust mode.
docs/security/auth.md advertises SCRAM-SHA-256 as the password-auth method but never mentions Trust mode being the default.
Source pointers
nodedb/src/config/auth.rs:200 — AuthMode::Trust is the default in AuthConfig::default().
nodedb/src/control/server/pgwire/factory.rs:179-180 — when AuthMode::Trust, startup handler is AuthStartup::Trust which just proceeds.
nodedb/src/control/server/pgwire/factory.rs:246-263 — the Trust branch of on_startup records an audit line ("trust auth: {username}") and returns Ok(()) without consulting credentials / the user catalog.
Related
Combined with issue #29 (tenant-scoped CREATE COLLECTION planner mismatch), this makes it hard to isolate multi-tenant deployments even when operators do everything "by the book" — running the default binary with CREATE TENANT + CREATE USER WITH PASSWORD doesn't produce the isolation the docs imply.
Also, CREATE TENANT acme auto-creates an acme_admin user with no password set. That's fine under Trust mode (password irrelevant), but becomes a latent zero-password account if operators later flip to AuthMode::Password.
Summary
With the default auth configuration (
AuthMode::Trust, the built-in default fromnodedb/src/config/auth.rs:200), any pgwire client can authenticate as any username — including usernames that were never created viaCREATE USER— with any password (including empty). Declared user passwords (CREATE USER alice WITH PASSWORD 'x') are silently ignored in Trust mode.docs/security/auth.mddoesn't mention Trust mode exists.Environment
nodedb-0.0.2-linux-arm64release binary127.0.0.1:6432b024c560nodedb.tomlconfigured — using built-in defaultspostgres.jsvia BunReproduction
All four connections succeed and return
[{ x: 1 }].Expected
At minimum, Trust mode should still verify the connecting username corresponds to a known user (matches PostgreSQL's
trustmethod behavior — it skips password verification but still resolves the role frompg_roles). Right now any fabricated username is accepted and presumably operates under some default identity.Ideally also:
docs/security/auth.mddocuments that Trust is the default and what it meansNODEDB_SUPERUSER_PASSWORDenv var on first boot, etc.)Actual
WITH PASSWORD '...'is dead metadata under Trust mode.docs/security/auth.mdadvertisesSCRAM-SHA-256as the password-auth method but never mentions Trust mode being the default.Source pointers
nodedb/src/config/auth.rs:200—AuthMode::Trustis the default inAuthConfig::default().nodedb/src/control/server/pgwire/factory.rs:179-180— whenAuthMode::Trust, startup handler isAuthStartup::Trustwhich just proceeds.nodedb/src/control/server/pgwire/factory.rs:246-263— the Trust branch ofon_startuprecords an audit line ("trust auth: {username}") and returnsOk(())without consultingcredentials/ the user catalog.Related
Combined with issue #29 (tenant-scoped CREATE COLLECTION planner mismatch), this makes it hard to isolate multi-tenant deployments even when operators do everything "by the book" — running the default binary with
CREATE TENANT+CREATE USER WITH PASSWORDdoesn't produce the isolation the docs imply.Also,
CREATE TENANT acmeauto-creates anacme_adminuser with no password set. That's fine under Trust mode (password irrelevant), but becomes a latent zero-password account if operators later flip toAuthMode::Password.