Con frecuencia es conveniente agrupar usuarios para facilitar la gestión de privilegios: de esa manera, los privilegios pueden ser otorgados a, o revocados de, un grupo en su totalidad. En PostgreSQL esto se hace creando un rol que representa al grupo, y luego otorgando pertenencia (membership) en el rol del grupo a roles de usuarios individuales.
Para configurar un rol de grupo, primero crea el rol:
CREATE ROLE name;
Normalmente, un rol que se utiliza como grupo no tendría el atributo LOGIN,
aunque puedes establecerlo si lo deseas.
Una vez que existe el rol de grupo, puedes agregar y eliminar miembros utilizando los comandos
GRANT y
REVOKE:
GRANTgroup_roleTOrole1, ... ; REVOKEgroup_roleFROMrole1, ... ;
También puedes otorgar pertenencia a otros roles de grupo (ya que realmente no hay
distinción entre roles de grupo y roles que no son de grupo). La base de datos no
te permitirá configurar bucles de pertenencia circulares. Además, no está
permitido otorgar pertenencia en un rol a PUBLIC.
Los miembros de un rol de grupo pueden utilizar los privilegios del rol de dos maneras.
En primer lugar, los roles miembros a los que se les ha concedido pertenencia con la
opción SET pueden hacer
SET ROLE para
temporariamente “convertirse” en el rol de grupo. En este estado, la
sesión de la base de datos tiene acceso a los privilegios del rol de grupo en lugar de
al rol de inicio de sesión original, y cualquier objeto de base de datos creado se considera
propiedad del rol de grupo, no del rol de inicio de sesión. En segundo lugar, los roles
miembros a los que se les ha concedido pertenencia con la opción INHERIT
automáticamente pueden usar los privilegios de aquellos de los que son miembros directa o
indirectamente, aunque la cadena se detiene en las pertenencias que carecen de la opción
inherit. Como ejemplo, supongamos que hemos hecho:
CREATE ROLE joe LOGIN; CREATE ROLE admin; CREATE ROLE wheel; CREATE ROLE island; GRANT admin TO joe WITH INHERIT TRUE; GRANT wheel TO admin WITH INHERIT FALSE; GRANT island TO joe WITH INHERIT TRUE, SET FALSE;
Inmediatamente después de conectarse como el rol joe, una sesión de
base de datos tendrá uso de los privilegios otorgados directamente a joe
más cualquier privilegio otorgado a admin y a island,
porque joe “hereda” esos privilegios. Sin embargo, los
privilegios otorgados a wheel no están disponibles, porque aunque
joe es miembro indirecto de wheel, la pertenencia
es a través de admin, que fue otorgada usando WITH INHERIT FALSE.
Después de:
SET ROLE admin;
la sesión tendría uso de sólo aquellos privilegios otorgados a admin,
y no los otorgados a joe o island. Después de:
SET ROLE wheel;
la sesión tendría uso de sólo aquellos privilegios otorgados a wheel,
y no los otorgados a joe o a admin. El estado original
de privilegios se puede restaurar con cualquiera de:
SET ROLE joe; SET ROLE NONE; RESET ROLE;
El comando SET ROLE siempre permite seleccionar cualquier rol
del cual el rol de inicio de sesión original es miembro directa o indirectamente,
siempre que haya una cadena de concesiones de pertenencia en la que cada una tenga
SET TRUE (que es el valor por defecto).
Por lo tanto, en el ejemplo anterior, no es necesario convertirse en
admin antes de convertirse en wheel.
Por otro lado, no es posible convertirse en island
en absoluto; joe sólo puede acceder a esos privilegios a través de
la herencia.
En el estándar SQL, hay una clara distinción entre usuarios y roles, y los
usuarios no heredan automáticamente los privilegios mientras que los roles sí. Este
comportamiento se puede obtener en PostgreSQL asignando a los
roles que se utilizan como roles SQL el atributo INHERIT, mientras que
a los roles que se utilizan como usuarios SQL se les asigna el atributo NOINHERIT.
Sin embargo, PostgreSQL tiene como valor predeterminado otorgar a todos
los roles el atributo INHERIT, para mantener la compatibilidad con las
versiones anteriores a la 8.1 en las que los usuarios siempre podían usar los permisos
otorgados a los grupos de los que eran miembros.
Los atributos de rol LOGIN, SUPERUSER,
CREATEDB y CREATEROLE se pueden considerar como
privilegios especiales, pero nunca se heredan como lo hacen los privilegios ordinarios
sobre los objetos de la base de datos. Realmente debes hacer SET ROLE
a un rol específico que tenga uno de estos atributos para hacer uso del mismo.
Continuando con el ejemplo anterior, podríamos optar por otorgar CREATEDB
y CREATEROLE al rol admin. Entonces, una sesión que
se conecte como el rol joe no tendría estos privilegios de inmediato,
sólo después de hacer SET ROLE admin.
Para destruir un rol de grupo, utiliza DROP ROLE:
DROP ROLE name;
Cualquier pertenencia en el rol de grupo se revoca automáticamente (pero los roles miembros no se ven afectados de otra manera).