5.8. Privileges #

When an object is created, it is assigned an owner. The owner is normally the role that executed the creation statement. For most kinds of objects, the initial state is that only the owner (or a superuser) can do anything with the object. To allow other roles to use it, privileges must be granted.

There are different kinds of privileges: SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER, CREATE, CONNECT, TEMPORARY, EXECUTE, USAGE, SET, ALTER SYSTEM, and MAINTAIN. The privileges applicable to a particular object vary depending on the object's type (table, function, etc.). More detail about the meanings of these privileges appears below. The following sections and chapters will also show you how these privileges are used.

The right to modify or destroy an object is inherent in being the object's owner, and cannot be granted or revoked in itself. (However, like all privileges, that right can be inherited by members of the owning role; see Section 21.3.)

An object can be assigned to a new owner with an ALTER command of the appropriate kind for the object, for example

ALTER TABLE table_name OWNER TO new_owner;

Superusers can always do this; ordinary roles can only do it if they are both the current owner of the object (or inherit the privileges of the owning role) and able to SET ROLE to the new owning role. All object privileges of the old owner are transferred to the new owner along with the ownership.

To assign privileges, the GRANT command is used. For example, if joe is an existing role, and accounts is an existing table, the privilege to update the table can be granted with:

GRANT UPDATE ON accounts TO joe;

Writing ALL in place of a specific privilege grants all privileges that are relevant for the object type.

The special role name PUBLIC can be used to grant a privilege to every role on the system. Also, group roles can be set up to help manage privileges when there are many users of a database — for details see Chapter 21.

To revoke a previously-granted privilege, use the fittingly named REVOKE command:

REVOKE ALL ON accounts FROM PUBLIC;

Ordinarily, only the object's owner (or a superuser) can grant or revoke privileges on an object. However, it is possible to grant a privilege with grant option, which gives the recipient the right to grant it in turn to others. If the grant option is subsequently revoked then all who received the privilege from that recipient (directly or through a chain of grants) will lose the privilege. For details see the GRANT and REVOKE reference pages.

El propietario de un objeto puede optar por revocar sus propios privilegios ordinarios, por ejemplo para hacer que una tabla sea de solo lectura tanto para sí mismo como para los demás. Pero los propietarios siempre se tratan como poseedores de todas las opciones de otorgamiento (grant options), por lo que siempre pueden volver a otorgarse sus propios privilegios.

Los privilegios disponibles son:

SELECT #

Permite realizar SELECT en cualquier columna, o columna(s) específica(s), de una tabla, vista, vista materializada u otro objeto similar a una tabla. También permite el uso de COPY TO. Este privilegio también es necesario para hacer referencia a valores de columnas existentes en UPDATE, DELETE o MERGE. Para las secuencias, este privilegio también permite el uso de la función currval. Para los objetos grandes (large objects), este privilegio permite la lectura del objeto.

INSERT #

Permite realizar INSERT de una nueva fila en una tabla, vista, etc. Se puede otorgar en columna(s) específica(s), en cuyo caso solo se les pueden asignar valores a esas columnas en el comando INSERT (por lo tanto, las demás columnas recibirán sus valores por defecto). También permite el uso de COPY FROM.

UPDATE #

Permite realizar UPDATE en cualquier columna, o columna(s) específica(s), de una tabla, vista, etc. (En la práctica, cualquier comando UPDATE no trivial también requerirá el privilegio SELECT, ya que debe hacer referencia a las columnas de la tabla para determinar qué filas actualizar, y/o para calcular los nuevos valores de las columnas). SELECT ... FOR UPDATE y SELECT ... FOR SHARE también requieren este privilegio en al menos una columna, además del privilegio SELECT. Para las secuencias, este privilegio permite el uso de las funciones nextval y setval. Para los objetos grandes, este privilegio permite escribir o truncar el objeto.

DELETE #

Permite realizar DELETE de una fila de una tabla, vista, etc. (En la práctica, cualquier comando DELETE no trivial también requerirá el privilegio SELECT, ya que debe hacer referencia a las columnas de la tabla para determinar qué filas eliminar).

TRUNCATE #

Permite realizar TRUNCATE en una tabla.

REFERENCES #

Permite la creación de una restricción de clave foránea que hace referencia a una tabla, o columna(s) específica(s) de una tabla.

TRIGGER #

Permite la creación de un disparador (trigger) en una tabla, vista, etc.

CREATE #

Para las bases de datos, permite crear nuevos esquemas y publicaciones dentro de la base de datos, y permite instalar extensiones de confianza (trusted extensions) dentro de la base de datos.

Para los esquemas, permite crear nuevos objetos dentro del esquema. Para renombrar un objeto existente, debes ser el propietario del objeto y tener este privilegio para el esquema que lo contiene.

Para los espacios de tablas (tablespaces), permite crear tablas, índices y archivos temporales dentro del espacio de tablas, y permite crear bases de datos que tengan el espacio de tablas como su espacio de tablas por defecto.

Ten en cuenta que revocar este privilegio no alterará la existencia ni la ubicación de los objetos existentes.

CONNECT #

Permite al beneficiario conectarse a la base de datos. Este privilegio se comprueba al iniciar la conexión (además de comprobar cualquier restricción impuesta por pg_hba.conf).

TEMPORARY #

Permite crear tablas temporales mientras se utiliza la base de datos.

EXECUTE #

Permite invocar una función o procedimiento, incluido el uso de cualquier operador que esté implementado sobre la función. Este es el único tipo de privilegio aplicable a funciones y procedimientos.

USAGE #

Para los lenguajes procedimentales, permite usar el lenguaje para la creación de funciones en ese lenguaje. Este es el único tipo de privilegio aplicable a los lenguajes procedimentales.

Para los esquemas, permite el acceso a los objetos contenidos en el esquema (asumiendo que también se cumplen los requisitos de privilegios de los propios objetos). Esencialmente, esto permite al beneficiario buscar (look up) objetos dentro del esquema. Sin este permiso, todavía es posible ver los nombres de los objetos, por ejemplo, mediante consultas a los catálogos del sistema. Además, después de revocar este permiso, las sesiones existentes podrían tener sentencias que hayan realizado previamente esta búsqueda, por lo que esta no es una forma completamente segura de evitar el acceso a los objetos.

Para las secuencias, permite el uso de las funciones currval y nextval.

Para los tipos y dominios, permite el uso del tipo o dominio en la creación de tablas, funciones y otros objetos de esquema. (Ten en cuenta que este privilegio no controla todo el uso del tipo, como los valores del tipo que aparecen en las consultas. Solo evita que se creen objetos que dependan del tipo. El propósito principal de este privilegio es controlar qué usuarios pueden crear dependencias en un tipo, lo que podría impedir que el propietario cambie el tipo más adelante).

Para los conectores de datos externos (foreign-data wrappers), permite la creación de nuevos servidores utilizando el conector de datos externos.

Para los servidores externos (foreign servers), permite la creación de tablas externas utilizando el servidor. Los beneficiarios también pueden crear, alterar o eliminar sus propias asignaciones de usuario (user mappings) asociadas con ese servidor.

SET #

Permite establecer un parámetro de configuración del servidor a un nuevo valor dentro de la sesión actual. (Aunque este privilegio se puede otorgar en cualquier parámetro, no tiene sentido excepto para los parámetros que normalmente requerirían privilegios de superusuario para ser establecidos).

ALTER SYSTEM #

Permite configurar un parámetro de configuración del servidor a un nuevo valor utilizando el comando ALTER SYSTEM.

MAINTAIN #

Permite ejecutar VACUUM, ANALYZE, CLUSTER, REFRESH MATERIALIZED VIEW, REINDEX, LOCK TABLE y funciones de manipulación de estadísticas de objetos de base de datos (consulta Table 9.105) en una relación.

Los privilegios requeridos por otros comandos se detallan en la página de referencia del comando respectivo.

PostgreSQL otorga privilegios sobre algunos tipos de objetos a PUBLIC de forma predeterminada cuando se crean los objetos. No se otorgan privilegios a PUBLIC por defecto en tablas, columnas de tablas, secuencias, conectores de datos externos, servidores externos, objetos grandes, esquemas, espacios de tablas o parámetros de configuración. Para otros tipos de objetos, los privilegios por defecto otorgados a PUBLIC son los siguientes: privilegios CONNECT y TEMPORARY (crear tablas temporales) para bases de datos; privilegio EXECUTE para funciones y procedimientos; y privilegio USAGE para lenguajes y tipos de datos (incluidos los dominios). El propietario del objeto puede, por supuesto, REVOKE tanto los privilegios por defecto como los otorgados expresamente. (Para una seguridad máxima, ejecuta el REVOKE en la misma transacción que crea el objeto; de este modo no hay ventana de tiempo en la que otro usuario pueda usar el objeto). Además, estas configuraciones de privilegios por defecto pueden ser anuladas utilizando el comando ALTER DEFAULT PRIVILEGES.

La Table 5.1 muestra las abreviaturas de una letra que se utilizan para estos tipos de privilegios en los valores de ACL. Verás estas letras en la salida de los comandos de psql que se enumeran a continuación, o al examinar las columnas de ACL de los catálogos del sistema.

Table 5.1. Abreviaturas de privilegios de ACL

PrivilegioAbreviaturaTipos de objetos aplicables
SELECTr (read, lectura) LARGE OBJECT, SEQUENCE, TABLE (y objetos similares a tablas), columna de tabla
INSERTa (append, anexado)TABLE, columna de tabla
UPDATEw (write, escritura) LARGE OBJECT, SEQUENCE, TABLE, columna de tabla
DELETEdTABLE
TRUNCATEDTABLE
REFERENCESxTABLE, columna de tabla
TRIGGERtTABLE
CREATEC DATABASE, SCHEMA, TABLESPACE
CONNECTcDATABASE
TEMPORARYTDATABASE
EXECUTEXFUNCTION, PROCEDURE
USAGEU DOMAIN, FOREIGN DATA WRAPPER, FOREIGN SERVER, LANGUAGE, SCHEMA, SEQUENCE, TYPE
SETsPARAMETER
ALTER SYSTEMAPARAMETER
MAINTAINmTABLE

La Table 5.2 resume los privilegios disponibles para cada tipo de objeto SQL, utilizando las abreviaturas mostradas anteriormente. También muestra el comando de psql que se puede utilizar para examinar la configuración de privilegios para cada tipo de objeto.

Table 5.2. Resumen de privilegios de acceso

Tipo de objetoTodos los privilegiosPrivilegios PUBLIC por defectoComando de psql
DATABASECTcTc\l
DOMAINUU\dD+
FUNCTION o PROCEDUREXX\df+
FOREIGN DATA WRAPPERUninguno\dew+
FOREIGN SERVERUninguno\des+
LANGUAGEUU\dL+
LARGE OBJECTrwninguno\dl+
PARAMETERsAninguno\dconfig+
SCHEMAUCninguno\dn+
SEQUENCErwUninguno\dp
TABLE (y objetos similares a tablas)arwdDxtmninguno\dp
Columna de tablaarwxninguno\dp
TABLESPACECninguno\db+
TYPEUU\dT+

Los privilegios que se han otorgado para un objeto en particular se muestran como una lista de entradas de tipo aclitem, cada una con el formato:

grantee=privilege-abbreviation[*].../grantor

Cada aclitem enumera todos los permisos de un beneficiario (grantee) que han sido otorgados por un otorgante (grantor) en particular. Los privilegios específicos se representan mediante abreviaturas de una letra de la Table 5.1, con un * añadido si el privilegio se otorgó con la opción de otorgamiento (grant option). Por ejemplo, calvin=r*w/hobbes especifica que el rol calvin tiene el privilegio SELECT (r) con opción de otorgamiento (*), así como el privilegio no otorgable UPDATE (w), ambos otorgados por el rol hobbes. Si calvin también tiene algunos privilegios sobre el mismo objeto otorgados por un otorgante diferente, estos aparecerían como una entrada de aclitem separada. Un campo de beneficiario vacío en un aclitem representa a PUBLIC.

Como ejemplo, supongamos que la usuaria miriam crea la tabla mytable y hace:

GRANT SELECT ON mytable TO PUBLIC;
GRANT SELECT, UPDATE, INSERT ON mytable TO admin;
GRANT SELECT (col1), UPDATE (col1) ON mytable TO miriam_rw;

Entonces el comando \dp de psql mostraría:

=> \dp mytable
                                  Access privileges
 Schema |  Name   | Type  |   Access privileges    |   Column privileges   | Policies
--------+---------+-------+------------------------+-----------------------+----------
 public | mytable | table | miriam=arwdDxtm/miriam+| col1:                +|
        |         |       | =r/miriam             +|   miriam_rw=rw/miriam |
        |         |       | admin=arw/miriam       |                       |
(1 row)

Si la columna Access privileges está vacía para un objeto dado, significa que el objeto tiene los privilegios por defecto (es decir, su entrada de privilegios en el catálogo del sistema correspondiente es nula). Los privilegios por defecto siempre incluyen todos los privilegios para el propietario, y pueden incluir algunos privilegios para PUBLIC dependiendo del tipo de objeto, como se explicó anteriormente. El primer GRANT o REVOKE sobre un objeto instanciará los privilegios por defecto (produciendo, por ejemplo, miriam=arwdDxt/miriam) y luego los modificará según la solicitud especificada. De manera similar, se muestran entradas en Column privileges solo para columnas con privilegios no predeterminados. (Nota: para este propósito, privilegios por defecto siempre significa los privilegios por defecto incorporados para el tipo de objeto. Un objeto cuyos privilegios hayan sido afectados por un comando ALTER DEFAULT PRIVILEGES siempre se mostrará con una entrada de privilegios explícita que incluye los efectos del ALTER.)

Ten en cuenta que las opciones de otorgamiento implícitas del propietario no se marcan en la visualización de privilegios de acceso. Solo aparecerá un * cuando las opciones de otorgamiento hayan sido otorgadas explícitamente a alguien.

La columna Access privileges muestra (none) cuando la entrada de privilegios del objeto no es nula pero está vacía. Esto significa que no se otorga ningún privilegio en absoluto, ni siquiera al propietario del objeto — una situación inusual. (El propietario todavía tiene opciones de otorgamiento implícitas en este caso, por lo que podría volver a otorgar sus propios privilegios; pero no tiene ninguno en este momento).