Algunas ocasiones es necesario crear usuarios explícitamente para lectura en una base de datos y como buena practica de seguridad siempre es bueno tener perfiles de accesos para los distintos tipos de roles que un usuario ó aplicación pudiera tener dentro de la base de datos.
Nos conectamos a la base de datos (test_db) donde vamos a aplicar estos privilegios y con un usuario privilegiado para poder hacer las modificaciones (postgres).
$ su - postgres -c 'psql -U postgres -d test_db'
Creamos el ROL read_user con privilegios limitados.
test_db=# CREATE ROLE read_user;
test_db=# CREATE ROLE read_user WITH LOGIN ENCRYPTED PASSWORD 'password' NOSUPERUSER INHERIT NOCREATEROLE NOREPLICATION NOCREATEDB;
Damos privilegio CONNECT
para que nuestro usuario read_user puede conectarse a la base de datos test_db, y USAGE
para usar el esquema que definamos, en nuestro caso public
test_db=# GRANT CONNECT ON DATABASE test_db TO read_user;
test_db=# GRANT USAGE ON SCHEMA public TO read_user;
Al usuario read_user le vamos a dar los privilegios de SELECT
en las todas las tablas en el SCHEMA public (Que por defecto es el esquema que usa postgresql para una base de datos) y el privilegio EXECUTE
sobre funciones en la base de datos.
test_db=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_user;
test_db=# GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO read_user;
Ahora bien los comandos anteriores solo tienen efecto sobre las tablas existentes, necesitamos modificar los privilegios por defecto de la base de datos test_db para que se apliquen los privilegios anteriores a nuevas tablas.
test_db=# ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT EXECUTE ON FUNCTIONS TO read_user;
test_db=# ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO read_user;
Para ver los privilegios actuales de las tables en la base de datos ejecutamos \z
en el cmd.
test_db=# \z
Access privileges
Schema | Name | Type | Access privileges | Column access privileges
----------+--------------------------+----------+---------------------------+-------------------
public | prueba_tabla | table | postgres=arwdDxt/postgres+|
| | | read_user=r/postgres |
Ahora creamos un usuario que herede los privilegios del Rol que definimos para un usuario de solo lectura.
test_db=# CREATE ROLE menganito WITH LOGIN ENCRYPTED PASSWORD 'password' NOSUPERUSER INHERIT NOCREATEROLE NOREPLICATION NOCREATEDB;
test_db=# GRANT read_user TO menganito;