Postgres: prevent new user from creating tables, without superuser - postgresql

In Cloud SQL Postgres, where superuser permissions are not accessible, how can I prevent a new user from creating tables?
I know that REVOKE CREATE ON SCHEMA public FROM public works, but this seem to require superuser permissions, as I get a WARNING: no privileges could be revoked for "public" error.

You have to run that statement as the user who owns public.

Related

CloudSQL Postgres confused around table grants and owners

I'm using CloudSQL Postgres 11 on GCP, and I've got a few questions around permissions and grants. I'm just not getting it at the moment, being very new to postgres.
I have a user, pgadmin which is a superuser. With this user I can connect to the instance and create a database called 'sandbox' for example.
I then have an app role which is defined as follows:
CREATE ROLE app;
GRANT CONNECT ON DATABASE <database name> TO app;
GRANT USAGE, CREATE ON SCHEMA public TO app;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO app;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO app;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO app;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE ON SEQUENCES TO app;
I create a user called app_sandbox which I grant this role.
The app user then makes a db migration using flyway which creates 2 tables. That side of things is fine.
But with my superuser, pgadmin, I can't see these tables or query them even though this user owns the database and is a superuser. I've tried all sorts of grants. Feels like I'm missing something important because even if I true to create a readonly role with the pgadmin user I am unable to grant access to the underlying tables in the public schema of the database.
What am I missing?
Just because one user (=pgadmin) owns the database, does not mean that user also owns the tables created in that database. And because pgadmin doesn't own those tables, you can't access them when logged in as pgadmin
If the app user created the tables, they belong to that user, and only the app user can grant privileges on those tables to other users.

Amazon RDS - Postgresql role cannot access tables

created a postgresql instance on AWS with the username ziggy. I restored a database to that instance. however I cannot even select any of the tables
select * FROM mac_childcare_parcels
gives me ERROR: permission denied for relation mac_childcare_parcels
********** Error **********
the owner of that table belongs to the postgres login.
so i tried running this: grant all privileges on all tables in schema public to ziggy but since I am not a superuser I cannot give myself privileges so that throws a permissions error. what do I have to do to get access to the tables?
this does not work either
grant select on mac_childcare_parcels to ziggy
this query returns successful but does not let the login ziggy access the tables
GRANT USAGE ON SCHEMA public TO ziggy;
First login with superuser and provide all rds superuser access to the newly created user using a command like below
GRANT rds_superuser TO ziggy;
replace rds_superuser with your rds superuser.
You need to also GRANT USAGE on the SCHEMA, e.g.
GRANT USAGE ON SCHEMA public TO ziggy;
The superuser access is needed to run the access level queries. But as you said that access is not present then i would say copy the replica of the db which you have restored from backup and grant yourself as superuser.
then provide all needed access to any users.

Permission denied to copy database

I'm still getting used to the concept of roles in Postgres.
I'm trying to create a role, migrator, that will have the ability to read from a production db and use it as a template to make stage and dev databases.
I've created this role migrator originally like so:
CREATE ROLE migrator LOGIN ENCRYPTED PASSWORD '<password>'
and proceeded to restrict access to the prod database:
REVOKE ALL ON DATABASE prod FROM PUBLIC;
GRANT CONNECT ON DATABASE prod TO migrator;
/* switch to prod database */
GRANT USAGE ON SCHEMA public TO migrator;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO migrator;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO migrator;
After trying a CREATE DATABASE stage TEMPLATE prod; and getting an error, I had to alter the role to create a db:
ALTER ROLE migrator CREATEDB;
and tried again. This time I got the error:
ERROR: permission denied to copy database "prod"
And again, I tried to add the replication permission to the migrator role (not sure if this is correct, as the manual says this is a very elevated permission)
ALTER ROLE migrator REPLICATION;
however, I still get the same error.
UPDATE: I've figured out that this has something to do with who owns the database; however, my problem remains. How can I allow another role with just READ privileges the ability to copy a database as well? I looked at role inheritance, but at first glance it looks like the inheriting role will just get the same permissions as the parent role.
It's not possible to copy a database unless the logged-in role is an owner or the database is flagged as a template:
datistemplate can be set to indicate that a database is intended as a template for CREATE DATABASE. If this flag is set, the database can be cloned by any user with CREATEDB privileges; if it is not set, only superusers and the owner of the database can clone it.

Revoke Create on public Schema from user - is not working in Postgresql

I am using postgresql -8.4.20 which is a back-end for JON server and login with username rhqadmin and connected to database rhq.
After connecting It is redirecting me to public schema by default.
Now I don't want to allow this user rhqadmin to create tables in public Schema.
So I am revoking the Create privilege on public schema by using following command:-
Revoke Create ON SCHEMA public FROM rhqadmin;
Then it is giving me warning -
"no privileges could be revoked for "public".
When I login with super user postgres and from there I revoke 'CREATE' privilege on public Schema for user rhqadmin then it is not giving any warning and successfully revoked then I logged in with user rhqadmin and try to create table in public schema and again it is allowing me to Create table even after revoking the create privilege from super user.
Please tell me why revoke privilege is not working for public Schema or I am doing any mistake.
Regards,
Avinash
Your problem is that the CREATE privilege is not granted to rhqadmin, but to the special role PUBLIC to which everybody belongs by default.
Since privileges in PostgreSQL are additive, there is no way to explicitly forbid something to only a single user if it is allowed to everybody.
The solution is probably:
REVOKE CREATE ON SCHEMA public FROM PUBLIC;

ERROR: permission denied for schema user1_gmail_com at character 46

I need to restrict a user, access only on a particualr schema tables only.So I tried following query and login as user1_gmail_com. But I got following error when I try to browse any schema table.
My Query:
SELECT clone_schema('my_application_template_schema','user1_gmail_com');
CREATE USER user1_gmail_com WITH PASSWORD 'myloginpassword';
REVOKE ALL ON ALL TABLES IN SCHEMA user1_gmail_com FROM PUBLIC;
GRANT SELECT ON ALL TABLES IN SCHEMA user1_gmail_com TO user1_gmail_com;
SQL error:
ERROR: permission denied for schema user1_gmail_com at character 46
In statement:
SELECT COUNT(*) AS total FROM (SELECT * FROM "user1_gmail_com"."organisations_table") AS sub
Updated Working Query:
SELECT clone_schema('my_application_template_schema','user1_gmail_com');
CREATE USER user1_gmail_com WITH PASSWORD 'myloginpassword';
REVOKE ALL ON ALL TABLES IN SCHEMA user1_gmail_com FROM PUBLIC;
GRANT USAGE ON SCHEMA user1_gmail_com TO user1_gmail_com;
GRANT SELECT ON ALL TABLES IN SCHEMA user1_gmail_com TO user1_gmail_com;
You need to grant access not only to the tables in the schema, but also to the schema itself.
From the manual:
By default, users cannot access any objects in schemas they do not own. To allow that, the owner of the schema must grant the USAGE privilege on the schema.
So either make your created user the owner of the schema, or grant USAGE on the schema to this user.
This confused me. Still not sure I'm handling it correctly. Run \h grant for the syntax within psql. Here is how I managed to get my other users and groups to work as I needed:
GRANT ALL PRIVILEGES ON SCHEMA foo TO GROUP bar;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA foo TO GROUP bar;
I kept getting this error when using flyway to deploy database changes. I do some manual setup first, such as creating the database, so flyway wouldn't need those super-admin permissions.
My Fix
I had to ensure that the database user that flyway job used had ownership rights to the public schema, so that the flyway user could then assign the right to use the schema to other roles.
Additional setup Details
I am using AWS RDS (both regular and Aurora), and they don't allow super users in the databases. RDS reserves super users for use by AWS, only, so that consumers are unable to break the replication stuff that is built in. However, there's a catch-22 that you must be an owner in postgres to be able to modify it.
My solution was to create a role that acts as the owner ('owner role'), and then assign both my admin user and the flyway user to the owner role, and use ALTER scripts for each object to assign the object's owner to the owner role.
I missed the public schema, since that was auto-created when I created the database script manually. The public schema defaulted to my admin role rather than the shared owner role. So when the flyway user tried to assign public schema permissions to other roles, it didn't have the authority to do that. An error was not thrown during flyway execution, however.