Skip to content

Create the Supabase roles a greenfield managed Postgres install needs - #3218

Open
p-hoffmann wants to merge 3 commits into
developfrom
p-hoffmann/service-role-without-bypassrls-develop
Open

Create the Supabase roles a greenfield managed Postgres install needs#3218
p-hoffmann wants to merge 3 commits into
developfrom
p-hoffmann/service-role-without-bypassrls-develop

Conversation

@p-hoffmann

Copy link
Copy Markdown
Member

No description provided.

Setting BYPASSRLS requires superuser, which managed Postgres never grants --
Azure Flexible Server has no superuser role at all, and even an account that
holds BYPASSRLS itself cannot confer it:

  ERROR:  must be superuser to change bypassrls attribute

So `CREATE ROLE service_role NOLOGIN INHERIT BYPASSRLS` has never succeeded on
those platforms. Because the surrounding catch only logs, pg-mgmt-init still
exited 0 with service_role missing, and it skipped the GRANTs that follow. The
failure then surfaced in supabase-storage-grant-roles as the misleading
`role "service_role" does not exist`.

Existing environments hide this: once someone creates the role by hand,
verifyIfUserExists short-circuits and the statement is never reached again.
Role OIDs on an affected environment show anon and authenticated created
together and service_role created separately much later, without BYPASSRLS --
consistent with a manual repair rather than a successful run.

Reachability of storage.buckets for service_role is provided by the
d2e_service_role_all policy in the d2e-core chart, so dropping the attribute
here loses nothing.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates bootstrap provisioning so managed PostgreSQL can create service_role without requiring superuser-only BYPASSRLS.

Changes:

  • Removes BYPASSRLS from service_role creation.
  • Updates unit coverage to verify the generated SQL excludes BYPASSRLS.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
services/trex/provision/d2e-bootstrap/bootstrap.ts Creates service_role with managed PostgreSQL-compatible attributes.
services/trex/provision/d2e-bootstrap/bootstrap.test.ts Validates the revised role attributes.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

V1__initial_schema creates supabase_admin WITH ... REPLICATION, which is
superuser-only on managed Postgres. The statement fails, V1 aborts, and the
whole trexdb schema is never created -- trex then dies on boot with
"trexdb.kek_wrapped_dek not present after 60000ms".

V1 is checksum-verified and already applied in existing deployments, so it
cannot be edited. Pre-creating the role makes V1's own IF NOT EXISTS guard
skip the failing statement, and granting membership lets V1 create the
_realtime schema with the role as owner. No REPLICATION is requested:
V5__drop_realtime_admin drops the role and that schema a few migrations
later, since native realtime replaced the external container.
@p-hoffmann
p-hoffmann force-pushed the p-hoffmann/service-role-without-bypassrls-develop branch from be99896 to ce19dbc Compare August 27, 2026 09:03
@p-hoffmann p-hoffmann changed the title Create service_role without BYPASSRLS Create the Supabase roles a greenfield managed Postgres install needs Aug 27, 2026
Two greenfield failures, both invisible on existing deployments:

Postgres 15 stopped granting CREATE on schema public to PUBLIC, and logto's
roles.sql creates public.check_role_type hardcoded to public rather than to
its own schema, so seeding a fresh database fails with "permission denied for
schema public". Grant it to the manage roles, with USAGE for the roles that
only read public.objects. public is owned by the platform admin role, so the
grant is a silent no-op unless the bootstrap user is a member of it -- check
the result and warn, rather than let it surface later as an unrelated error.

supabase-storage connects as POSTGRES_SUPERUSER, so on a fresh install that
role owns storage.objects and only it can disable row level security there.
Run the storage post-init as the superuser, joining the config admin role
first so it still owns the tables on older installs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants