Fix settlements runtime role provisioning - #14
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 54ccfbb640
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
|
|
||
| function schemaFrom(value) { | ||
| return new URL(value).searchParams.get('schema') || 'public'; |
There was a problem hiding this comment.
Honor search_path when selecting the grant schema
The runtime connection helper in src/index.ts accepts search_path as an alternative to schema, but this provisioner only reads the schema query parameter. In deployments using a supported URL like SETTLEMENTS_MIGRATION_DATABASE_URL=...?search_path=tenant,public, the grants are issued for public instead of the schema where the app will query its tables (or the script fails if those tables are absent), leaving settlements_app without access after provisioning. Please parse the first search_path entry the same way as the runtime or reject search_path explicitly.
Useful? React with 👍 / 👎.
| ['settlements_app'], | ||
| ); | ||
| const role = rows[0]; | ||
| if (!role?.rolcanlogin || role.rolsuper || role.rolcreatedb || role.rolcreaterole || role.rolinherit || role.rolbypassrls) { |
There was a problem hiding this comment.
Reject role memberships before certifying the role
When the migration takes the existing-role path, any memberships already granted to settlements_app are preserved, but this policy check still passes. In a cluster where that pre-existing role is a member of pg_read_all_data or another privileged role, NOINHERIT stops automatic inheritance but the login can still SET ROLE through memberships with the default SET permission, bypassing the intended table-scoped runtime policy. Please reject or revoke pg_auth_members entries for this role before considering provisioning successful.
Useful? React with 👍 / 👎.
| IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'settlements_app') THEN | ||
| CREATE ROLE settlements_app LOGIN; | ||
| END IF; | ||
| ALTER ROLE settlements_app NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOBYPASSRLS; |
There was a problem hiding this comment.
Clear replication privilege on reused roles
When settlements_app already exists, this ALTER ROLE does not reset the REPLICATION attribute, so a reused role that previously had replication privileges keeps them while still passing the provisioner’s runtime-policy check. In environments whose pg_hba allows password-authenticated replication connections, the newly provisioned app password could then stream WAL instead of being limited to the settlement tables. Add NOREPLICATION here and verify rolreplication before accepting the role.
Useful? React with 👍 / 👎.
Summary
Validation