ERROR: permiso denegado para el nombre de la tabla de relación en Postgres al intentar SELECT como usuario de solo lectura

89
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;

El usuario de solo lectura puede conectarse, ver las tablas, pero cuando intenta hacer una selección simple obtiene:

ERROR: permission denied for relation mytable
SQL state: 42501

Esto está sucediendo en PostgreSQL 9.1

¿Que hice mal?

sorin
fuente
1
¿Puede proporcionar algunos detalles sobre "relación mytable"? Esquema, es una tabla "real" (o una vista / función), disparadores ...
Igor Romanchenko

Respuestas:

162

Aquí está la solución completa para PostgreSQL 9+, actualizada recientemente.

CREATE USER readonly  WITH ENCRYPTED PASSWORD 'readonly';
GRANT USAGE ON SCHEMA public to readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly;

-- repeat code below for each database:

GRANT CONNECT ON DATABASE foo to readonly;
\c foo
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly; --- this grants privileges on new tables generated in new database "foo"
GRANT USAGE ON SCHEMA public to readonly; 
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;

Gracias a https://jamie.curle.io/creating-a-read-only-user-in-postgres/ por varios aspectos importantes

Si alguien encuentra un código más corto, y preferiblemente uno que pueda realizar esto para todas las bases de datos existentes, felicitaciones adicionales.

sorin
fuente
6
¿Esto incluye vistas?
Frank Conry
9
¿Por qué otorga el GRANT ALLpermiso de forma predeterminada al usuario de solo lectura?
Slava Fomin II
1
Di exactamente como está definido, sigue siendo el error sam
Anish Gopinath
puede confirmar los derechos otorgados usando \ddp. Debería mostrarse igual =r/que granting_user=r/readonly_userpara el acceso de solo lectura.
Greg Bray
Este es SQL literal de la pregunta. No veo cómo proporciona una solución.
r351574nc3
12

Intenta agregar

GRANT USAGE ON SCHEMA public to readonly;

Probablemente no sabía que es necesario tener los permisos necesarios para un esquema para poder usar objetos en el esquema.

sufriR
fuente
Algo extraño está sucediendo, corro estos comandos en el servidor utilizando psqlcomo postgresusuario y hago obtener una respuesta adecuada, GRANT. Aún así, cuando miro a la ACL en las tablas, solo veo otras dos cuentas, una es el propietario de la base de datos jirausery otra cuenta de solo lectura con el nombre qauser. Pero mi readonlyno aparece ahí. Postgres es la versión 9.1 e incluso reinicié el servidor, todavía no pasa nada.
sorin
2
¿Cuál es / fue la salida de \ du en la consola psql? ¿Todavía puedes dar este resultado o ya está arreglado como en tu respuesta?
SufleR
Realmente no sé qué sucedió, ya que el resultado fue correcto (GRANT). Ayer no funcionó, pero hoy funcionó después de ejecutar, nuevamente, los 3 comandos.
sorin
3
Nota: La respuesta esperada a esto es simplemente 'GRANT'. Si ve 'ADVERTENCIA: no se otorgaron privilegios para "público"', NO funcionó. El usuario de solo lectura no puede otorgarse permisos adicionales. Solo un usuario con permisos 'GRANT' puede hacer eso, por lo que probablemente deba iniciar sesión como superusuario.
PeterVermont
Hola, cuando trato de OTORGAR SELECCIONAR EN TODAS LAS TABLAS EN ESQUEMA public TO postgres; responde: ERROR: permiso denegado para relación databasechangeloglock. ¿Sabes lo que estoy haciendo mal? Gracias (sucede en GAppEngine Posgres9.6 usando la dirección pública y accediendo a través de la terminal)
Mike
-5

Esto funcionó para mí:

Compruebe el rol actual en el que ha iniciado sesión mediante: SELECT CURRENT_USER, SESSION_USER;

Nota : debe coincidir con el propietario del esquema.

Esquema | Nombre | Tipo | Propietario
-------- + -------- + ------- + ----------

Si el propietario es diferente, otorgue todas las concesiones al rol de usuario actual desde el rol de administrador de la siguiente manera:

GRANT 'ROLE_OWNER' a 'CURRENT ROLENAME';

Luego intente ejecutar la consulta, le dará el resultado ya que ahora tiene acceso a todas las relaciones.

Dhwani Shah
fuente
5
Cambiar el propietario a un usuario llamado readonly difícilmente suena como la solución correcta.
Anna
Dependiendo de su caso, el dueño de la mesa incorrecto puede ser la causa (era mi enemigo).
Forma
-6

asegúrese de que su usuario tenga atributos en su función. por ejemplo:

postgres=# \du
                             List of roles
 Role name |                   Attributes                   | Member of 
-----------+------------------------------------------------+-----------
 flux      |                                                | {}
 postgres  | Superuser, Create role, Create DB, Replication | {}

después de realizar el siguiente comando:

postgres=# ALTER ROLE flux WITH Superuser;
ALTER ROLE
postgres=# \du
                             List of roles
 Role name |                   Attributes                   | Member of 
-----------+------------------------------------------------+-----------
 flux      | Superuser                                      | {}
postgres  | Superuser, Create role, Create DB, Replication | {}

solucionó el problema.

vea el tutorial para roles y cosas aquí: https://www.digitalocean.com/community/tutorials/how-to-use-roles-and-manage-grant-permissions-in-postgresql-on-a-vps--2

PuN1sh3r
fuente
18
¡No! Dar el rol de superusuario a un usuario llamado "solo lectura" para hacer una "selección" no es la solución correcta.
Anna
@Anna Eso no es lo que está pasando aquí. Este hilo no se trata de dar acceso de solo lectura. Este hilo trata sobre dar acceso a un usuario para dar a otro usuario acceso de solo lectura. En mi humilde opinión, esto es correcto. Si su usuario no es un superusuario, no puede crear un usuario de solo lectura. El error que se está encontrando es por poder crear un usuario de solo lecturaERROR: permission denied for relation mytable
r351574nc3
-7

Debe ejecutar la siguiente consulta:

GRANT ALL ON TABLE mytable TO myuser;

O si su error está en una vista, tal vez la tabla no tenga permiso, por lo que debe ejecutar la siguiente consulta:

GRANT ALL ON TABLE tbm_grupo TO myuser;
Si
fuente
5
El usuario se denomina "solo lectura". Es dudoso que el objetivo sea otorgarle al usuario todos los permisos. Solo quiere hacer una selección.
Anna
Esto anula el propósito de nombrar al usuario 'ReadOnly' si le está dando ALTER DROP DELETEEct. Para ese usuario ...
JayRizzo