Revoke access to postgres database for a role - postgresql

I have created a separate role "newrole" and new schema "newschema" for a certain user that should only execute some stored functions. I have managed to revoke access to schema "public" for the current database.
Logged in as "newrole" I still have access to postgres database like this:
SELECT * FROM pg_user
I want to revoke all access to the postgres database and tried following that not work:
REVOKE ALL ON DATABASE postgres FROM newrole
When logged in as newrole I can still read the postgres database.
How do I revoke any access to the postgres admin database?
I have searched a long time but not found anything regarding access to the postgres admin database.
TIA,

This issue has nothing to do with database postgres. Instead, you want to manipulate the catalog of the current database. Every database has a catalog of information on all objects in schema pg_catalog, and in standards-compliant form in schema information_schema, so you should restrict access to those for the role in question and also for the public role because every role is also member of that role:
REVOKE ALL PRIVILEGES ON SCHEMA pg_catalog FROM newrole;
REVOKE ALL PRIVILEGES ON SCHEMA pg_catalog FROM public;
REVOKE ALL PRIVILEGES ON SCHEMA information_schema FROM newrole;
REVOKE ALL PRIVILEGES ON SCHEMA information_schema FROM public;
However, the system does not always honour this accross-the-board restriction, the catalogs are there for a reason and provide important functions in the database. Particularly functions may still execute.
In general, you do not want to fiddle with the catalogs unless you really know what you are doing.

you should be able to run this:
select * FROM information_schema.table_privileges where grantee = 'newrole';
to display all the privileges for newrole. With that information you should be able to explicitly revoke everything other than access to 'newschema'

Related

How to provide read only access to all existing databases in postgresql

what's the recommended way to provide readonly access to all databases in postgresql version 12.
I am using this found at How do you create a read-only user in PostgreSQL?
CREATE ROLE readaccess;
CREATE USER my_user_test WITH PASSWORD 'my_user_test';
GRANT readaccess TO my_user_test;
\c database_name;
-- need to connect to the database first on which we need to execute the below commands
GRANT CONNECT ON DATABASE database_name TO readaccess;
GRANT USAGE ON SCHEMA public TO readaccess;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readaccess;
-- Assign permissions to read all newly tables created in the future
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readaccess;
But using this approach I need to individually connect to each database and provide the role read only access.
Is there a better approach to provide a read only access all existing databases at once?
Thanks.

Postgres - how can I restrict the privilege to create/drop a table?

I would like to create "read-only privileges" in a PostgreSQL database (including the restriction of creating or dropping tables).
My strategy is to create a group with these privileges and then add roles that have had all their privileges revoked. In that way, the only inherit privileges when part of the read-only group.
I used the following commands to create privileges but it seems roles can add, delete tables when they join the group:
role_test_db=# REVOKE ALL ON DATABASE role_test_db FROM select_access_group;
REVOKE
role_test_db=# GRANT CONNECT ON DATABASE role_test_db TO select_access_group;
GRANT
role_test_db=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO select_access_group;
GRANT
I was reading the documentation and it seems like creating tables would be under CREATE privilege but I have not granted this. Can some explain why users part of this group can still make tables?
There are several mistakes:
Revoking privileges on the database does not restrict user's rights to create objects. For that, you have to revoke privileges on the schemas.
You can only REVOKE privileges that were GRANTed (by default or explicitly). I doubt that select_access_group has ever been granted any privileges on the database.
You likely forgot to revoke the dangerous default CREATE privilege on schema public. Connect as superuser and run
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
A user can only revoke privileges that were granted directly by that user
https://www.postgresql.org/docs/13/sql-revoke.html
See privileges
\du
select * from pg_roles;
Change (base) prilileges under admin role (postgres)

Postgres: granting access to a role/user for future tables created by a different role/user

I'm building a spring boot application. Flyway database migrations are executed at the application startup.
I decided to use two different roles: role__app (read/write rights on tables, sequences in app schema) and role__migration (advanced rights in app/migration schemas).
Flyway migrations are executed under role__migration so it becomes the owner of the created objects. I thought that the following statements would help:
ALTER DEFAULT PRIVILEGES IN SCHEMA app GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO role__app;
ALTER DEFAULT PRIVILEGES IN SCHEMA app GRANT USAGE ON SEQUENCES TO role__app;
But when the new tables are added to the app schema the user__app (belongs to the role__app) doesn't have access to the tables.
Is it possible to maintain such a flow (with app, migrattion users/roles) by Postgres or by any other means?
As a side note I should mention that I run the following statements on the target database:
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
REVOKE ALL ON DATABASE myDb FROM PUBLIC;
Update 1
I added the FOR ROLE clause, yet I'm still getting the permission denied message for a created table (app.property) in app schema for user user__app. The owner of the table is user__mig.
Update 2
After logging in as postgres user in dbeaver we can see that user__mig has all necessary permissions ticked whereas the user__app has no permissions on the app.property table at all:
Here is a gist to reproduce the problem: https://gist.github.com/happygrizzly/849a6a791f028ba5b191f73180ae35d1
You should write
ALTER DEFAULT PRIVILEGES FOR USER role__migration ...
If you omit the FOR USER clause, the privileges are only granted on objects created by the user who ran ALTER DEFAULT PRIVILEGES.
With the above statement, the privileges are granted when role__migration creates an object. That does not extend to members of the role role__migration.

Setting PostgreSQL privileges for a remote connection

I want to set a user which I can use remote, that for a database can:
do any rows operations
can't add new columns
can't delete/create database or tables
I don't want the user to have access to other databases
I executed:
GRANT ALL PRIVILEGES ON DATABASE "example" to user_name;
REVOKE CREATE ON DATABASE "example" FROM user_name;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO user_name;
The following fails:
REVOKE CREATE ALL TABLES IN SCHEMA public FROM user_name;
invalid privilege type CREATE for relation
Can you, please, add all necessary steps.
Also,:
some help to what to set in pg_admin drop, to import only data remotely.
In Ubuntu set/activate full search
You probably want to keep the user from crating tables in schema public.
For that, you must revoke the CREATE privilege on that schema which is by default granted to everybody:
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
If you want to user to have permissions on tables that will be created in the future, consider using ALTER DEFAULT PRIVILEGES.

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.