Separate PostgresQL runtime and schema ownership - #1752
Draft
Jeremy Alvis (iplay88keys) wants to merge 10 commits into
Draft
Jeremy Alvis (iplay88keys) wants to merge 10 commits into
Jeremy Alvis (iplay88keys) wants to merge 10 commits into
Conversation
Jeremy Alvis (iplay88keys)
marked this pull request as ready for review
September 18, 2026 21:38
…s-runtime-ddl-roles
…s-runtime-ddl-roles
Jeremy Alvis (iplay88keys)
marked this pull request as draft
September 22, 2026 15:58
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #997
Summary
ateapiseparate PostgreSQL owner and read/write connections. Migrations and owner maintenance use the owner pool; application reads and writes use the read/write pool. Each connection assumes its configured group role, so an operator can replace a login without changing object ownership.ateapiruns default to bootstrap disabled.@file:/absolute/pathfor both owner and read/write connection strings. Substrate rereads each projected Secret file when opening a new physical connection, so rotated credentials can take effect without restarting the process. The--postgres-max-conn-lifetimeCLI flag sets the maximum connection lifetime, bounding how long old connections remain in use; endpoint or database changes still require a restart.ate-setupand the installation manifests. The shell installer now delegates toate-setup. Its previous single-connection environment variable still supplies both pools when used alone and remains the owner connection when a separate read/write DSN is added. Bundled PostgreSQL requires password authentication plus its existing client certificate check. Standalone Substrate keepspublicas its default schema.Scope
This identity layout requires a fresh PostgreSQL database. The PR does not migrate existing users, grants, or tables into it.
The bundled-database installers enable bootstrap to provision Substrate's fixed identities.
ateapialso accepts explicit administrator and application connections for a managed shared database; it has no way to infer which deployment owns PostgreSQL. Deployments using operator-managed users disable bootstrap and provide precreated roles, memberships, schema, and grants.Cloud SQL intentionally uses one IAM database login by default. The owner connection defaults to the read/write connection, and each pool assumes its configured role. Separate logins remain supported through separate connection strings, but requiring two IAM logins would add proxy identity setup. Two logins limit exposure if only the read/write credential leaks; because
ateapiholds both pools, they do not isolate a compromisedateapipod. Stronger isolation would require moving owner operations out of that pod.The bootstrap usernames and passwords are fixed, published development credentials. Do not enable fixed-identity bootstrap against a production database. For production, provision unique logins and permissions outside
ateapi, supply their connection strings, and leave bootstrap disabled.