Skip to content

pgwire: tenant users get 'unknown table' on INSERT/SELECT against their own collections #29

Description

@hollanf

Summary

When a tenant-scoped user (any tenant other than tenant 1) connects via pgwire and runs INSERT or SELECT on a collection owned by their tenant, the query fails with unknown table — even though SHOW COLLECTIONS lists the collection and CREATE COLLECTION just succeeded on the same connection.

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 (post-ci(release): add Discord notification job for new releases #28 merge)
  • Client: postgres.js via Bun, prepare: false (still hits QueryParser::parse_sql via the extended Parse/Bind/Execute flow)

Reproduction

-- as superuser (tenant 1)
CREATE TENANT acme;
-- ok — assigns tenant_id = 2

CREATE USER svc WITH PASSWORD 'x' ROLE readwrite TENANT 2;
-- ok

Reconnect as svc on pgwire :6432:

CREATE COLLECTION t2_mem TYPE DOCUMENT STRICT (
    id STRING PRIMARY KEY,
    content STRING NOT NULL
);
-- OK

SHOW COLLECTIONS;
-- lists t2_mem with owner=svc

INSERT INTO t2_mem (id, content) VALUES ('a', 'alpha');
-- ERROR: unknown table: t2_mem

SELECT * FROM t2_mem;
-- ERROR: unknown table: t2_mem

Same behaviour with tenant_admin role (e.g. the auto-created acme_admin).

Expected

A tenant 2 user should be able to INSERT/SELECT on a collection that CREATE COLLECTION just persisted without error and that SHOW COLLECTIONS lists as theirs.

Actual

unknown table on every INSERT/SELECT against a non-tenant-1 collection. Works normally as the default superuser (tenant 1).

Asymmetric cross-tenant shape (same behaviour, opposite side)

From SQL Result
tenant-2 user SELECT * FROM <tenant-1-collection> returns [] (empty) silently
tenant-1 user SELECT * FROM <tenant-2-collection> unknown table error
tenant-2 user SELECT * FROM <own tenant-2 collection> unknown table error

Storage-level data isolation itself holds — no actual row leak across tenants. But the parse-vs-execute tenant mismatch makes every tenant > 1 unable to see its own collections through the planner.

Source pointer

nodedb/src/control/server/pgwire/handler/prepared/parser.rs:37-42try_infer_types in NodeDbQueryParser.

For cross-reference, the DDL path at nodedb/src/control/server/pgwire/ddl/collection/create/handler.rs:56 reads identity.tenant_id correctly, which is why CREATE COLLECTION and SHOW COLLECTIONS work but subsequent planning does not.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:pgwirePostgreSQL wire protocol / client compatsev:2-highMajor functionality broken; no acceptable workaroundtype:bugA defect — broken, incorrect, or lost data

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions