I need an non-superuser to create dbs and users, and assign this users to its respective DB, but this "start" user should not be able to delete other DBs or basically nothing more than create users and DBs.
I have this code, it can create DBs and users, but cant assign the DB to the created users. It returns: must be member of role "…":
CREATE ROLE starter NOSUPERUSER LOGIN CREATEDB CREATEROLE NOREPLICATION NOBYPASSRLS NOINHERIT WITH ENCRYPTED PASSWORD 'mypassword';
REVOKE SELECT,INSERT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER ON ALL TABLES IN SCHEMA public FROM starter;
*Also tried with create user
Is there a way to allow "starter" user to add owner to a DB?
I’m using this query for that:
CREATE DATABASE newdatabase OWNER test;
Output:
ERROR: must be member of role "test"
2
Answers
I found a solution or fix to achieve this, inspired by Chris' idea and this article (and own work). First the setup, as super user:
That creates the role "switch" and the "userCreateAccount", both nonsuperuser and with restricted privileges. Now using "userCreateAccount" in psql:
Now, being "UserCreateAccount" and "NewUser" on "Switch" role, and "NewDB" owned by switch, i just simple reassign ownership. As "NewUser" in psql:
Finally, but don't know if necessary as UserCreateAccount in psql:
Done that, i can use the whole NewDB and owned by NewUser
The short answer is not really, certainly not without a fair bit of custom extension. Basically. since
CREATE DATABASE
isn’t transactionally safe, it cannot be called from a function, or even a stored procedure (I tried).The result is that a non-superuser can only assign a database to a role he or she is a member of.
There are a couple of things that could be done instead: you could create a "parked" role that databases could go into until being claimed, and then you could have everyone be a member of that parked role, and then able to claim the databases.
It ought to be possible to solve this with a C-language extension too but this would not work on managed services.
As an additional note based on the comment, you are likely to need to run
REASSIGN OWNED
when claiming the database (https://www.postgresql.org/docs/current/sql-reassign-owned.html)