Crear usuario de lectura (read-only) en PostgreSQL

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;

Armando Uch

An Accidental Engineer
• Lazy #Programmer • #TacOps 🌮 • #BOFH
🎸⚾️🍺☕️


2014-06-27