You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Today DB_USERNAME=postgres and POSTGRES_USER=postgres locally, and pytest_postgresql hands the test suite a superuser. Verified: a superuser reads every row even with policies present, RLS enabled, and FORCE ROW LEVEL SECURITY set — silently. So without parity, the first real exercise of the security boundary is production, and the test suite would pass while enforcing nothing.
Scope
A docker-entrypoint-initdb.d mount running bootstrap-roles.sql. No such mount exists today, which is why roles are created nowhere.
settings/.env.dev: DB_USERNAME=mavedb_api, keeping POSTGRES_USER=postgres as the cluster owner.
tests/conftest.py: the session fixture creates the roles and connects as mavedb_api.
Note that the test suite builds schema with Base.metadata.create_all, not alembic, so policies must also exist as after_create DDL events (#809) for any of this to be meaningful.
Acceptance criteria
Local stack and CI both connect as a non-superuser, non-owner role.
A test asserts the fixture role is not a superuser, has no inherited rolbypassrls, and is NOINHERIT.
Existing tests pass under the demoted role — this is where missing grants surface.
Closing as a duplicate of #834, which covers the same three surfaces — the docker-entrypoint-initdb.d mount, .env.dev's DB_USERNAME, and the conftest.py session fixture — and additionally owns the get_current_user override, which is the fixture that would have silently invalidated the canary and the differential matrix.
The one acceptance criterion here that #834 did not already carry was that the fixture role hold no inheritedrolbypassrls. That distinction is worth keeping and has been folded into #834.
The other distinct criterion — that the fixture role be NOINHERIT — is not carried over, because it is wrong in the same direction the design record warns about. #827 creates mavedb_api with plain LOGIN, so this criterion would have failed against its own foundation script. More importantly, NOINHERIT is precisely the configuration log #35 identifies as reporting green while retaining the ability to SET ROLE: a NOINHERIT member of mavedb_system shows USAGE false and can still elevate itself and read every row. The property to assert is "member of nothing", tested with pg_has_role(..., 'MEMBER') — which #834 now states explicitly.
#808's sequencing step 0 has been updated to list #827 and #834 only.
Activity
bencap commentedon Aug 7, 2026
Closing as a duplicate of #834, which covers the same three surfaces — the
docker-entrypoint-initdb.dmount,.env.dev'sDB_USERNAME, and theconftest.pysession fixture — and additionally owns theget_current_useroverride, which is the fixture that would have silently invalidated the canary and the differential matrix.The one acceptance criterion here that #834 did not already carry was that the fixture role hold no inherited
rolbypassrls. That distinction is worth keeping and has been folded into #834.The other distinct criterion — that the fixture role be
NOINHERIT— is not carried over, because it is wrong in the same direction the design record warns about. #827 createsmavedb_apiwith plainLOGIN, so this criterion would have failed against its own foundation script. More importantly,NOINHERITis precisely the configuration log #35 identifies as reporting green while retaining the ability toSET ROLE: aNOINHERITmember ofmavedb_systemshowsUSAGEfalse and can still elevate itself and read every row. The property to assert is "member of nothing", tested withpg_has_role(..., 'MEMBER')— which #834 now states explicitly.#808's sequencing step 0 has been updated to list #827 and #834 only.