J'essaie de créer pour la première fois une base de données Postgres, alors c'est probablement une question stupide. J'ai attribué des autorisations de base en lecture seule au rôle de base de données qui doit accéder à la base de données à partir de mes scripts php, et j'ai une curiosité: si j'exécute
GRANT some_or_all_privileges ON ALL TABLES IN SCHEMA schema TO role;
est-il nécessaire d'exécuter également
GRANT USAGE ON SCHEMA schema TO role;
?
De documentation :
USAGE: pour les schémas, permet d'accéder aux objets contenus dans le schéma spécifié (en supposant que les exigences en matière de privilèges de ces objets soient également remplies). Cela permet essentiellement au bénéficiaire de "rechercher" des objets dans le schéma.
Je pense que si je peux sélectionner ou manipuler les données contenues dans le schéma, je peux accéder à n’importe quel objet du schéma lui-même. Ai-je tort? Si non, quel GRANT USAGE ON SCHEMA
est utilisé pour? Et que signifie exactement la documentation avec "en supposant que les exigences en matière de privilèges des objets soient également remplies"?
GRANT
s sur différents objets sont séparés. GRANT
ing sur une base de données n'a pas GRANT
droits sur le schéma à l'intérieur. De même, GRANT
ing sur un schéma n'accorde pas de droits sur les tables qu'il contient.
Si vous possédez des droits sur SELECT
à partir d'une table, mais que vous n'avez pas le droit de les voir dans le schéma qui les contient, vous ne pouvez pas accéder à la table.
Les tests de droits sont effectués dans l'ordre:
Do you have `USAGE` on the schema?
No: Reject access.
Yes: Do you also have the appropriate rights on the table?
No: Reject access.
Yes: Check column privileges.
Votre confusion peut provenir du fait que le schéma public
a une valeur par défaut GRANT
de tous les droits sur le rôle public
, dont chaque utilisateur/groupe est membre. Donc, tout le monde a déjà une utilisation sur ce schéma.
La phrase:
(en supposant que les propres exigences de privilège des objets soient également satisfaites)
Cela veut dire que vous devez avoir USAGE
sur un schéma pour utiliser les objets qu'il contient, mais avoir USAGE
sur un schéma n'est pas suffisant en soi pour utiliser les objets du schéma, vous devez également avoir des droits. sur les objets eux-mêmes.
C'est comme une arborescence de répertoires. Si vous créez un répertoire somedir
contenant le fichier somefile
, configurez-le de sorte que seul votre propre utilisateur puisse accéder au répertoire ou au fichier (mode rwx------
sur le répertoire, mode rw-------
sur le fichier), personne d’autre ne peut répertorier le répertoire pour vérifier que le fichier existe.
Si vous accordiez des droits de lecture sur le fichier (mode rw-r--r--
) mais ne changez pas les permissions du répertoire, cela ne changera rien. Personne ne pourrait voir le fichier pour le lire, car ils ne disposent pas des droits nécessaires pour répertorier le répertoire.
Si vous définissez plutôt rwx-r-xr-x
sur le répertoire, le paramétrant de manière à ce que les utilisateurs puissent répertorier et parcourir ce répertoire sans modifier les autorisations de fichiers. Les utilisateurs pouvaient list le fichier mais ne pouvaient pas le lire parce qu'ils ' ne pas avoir accès au fichier.
Vous devez définir les autorisations les deux pour que les utilisateurs puissent réellement consulter le fichier.
Même chose dans Pg. Vous avez besoin à la fois des droits de schéma USAGE
et des droits d'objet pour exécuter une action sur un objet, comme SELECT
à partir d'une table.
(L'analogie tombe un peu dans le fait que PostgreSQL n'a pas encore de sécurité au niveau de la ligne, ainsi l'utilisateur peut toujours "voir" que la table existe dans le schéma de SELECT
ing à partir de pg_class
directement. Ils ne peuvent interagir avec elle de quelque manière que ce soit, alors c'est juste la partie "liste" qui n'est pas tout à fait la même.)
Pour un système de production, vous pouvez utiliser cette configuration:
--ACCESS DB
REVOKE CONNECT ON DATABASE nova FROM PUBLIC;
GRANT CONNECT ON DATABASE nova TO user;
--ACCESS SCHEMA
REVOKE ALL ON SCHEMA public FROM PUBLIC;
GRANT USAGE ON SCHEMA public TO user;
--ACCESS TABLES
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM PUBLIC ;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only ;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO read_write ;
GRANT ALL ON ALL TABLES IN SCHEMA public TO admin ;
Eh bien, voici ma solution finale pour une base de données simple, pour Linux:
# Read this before!
#
# * roles in postgres are users, and can be used also as group of users
# * $ROLE_LOCAL will be the user that access the db for maintenance and
# administration. $ROLE_REMOTE will be the user that access the db from the webapp
# * you have to change '$ROLE_LOCAL', '$ROLE_REMOTE' and '$DB'
# strings with your desired names
# * it's preferable that $ROLE_LOCAL == $DB
#-------------------------------------------------------------------------------
//----------- SKIP THIS PART UNTIL POSTGRES JDBC ADDS SCRAM - START ----------//
cd /etc/postgresql/$VERSION/main
Sudo cp pg_hba.conf pg_hba.conf_bak
Sudo -e pg_hba.conf
# change all `md5` with `scram-sha-256`
# save and exit
//------------ SKIP THIS PART UNTIL POSTGRES JDBC ADDS SCRAM - END -----------//
Sudo -u postgres psql
# in psql:
create role $ROLE_LOCAL login createdb;
\password $ROLE_LOCAL
create role $ROLE_REMOTE login;
\password $ROLE_REMOTE
create database $DB owner $ROLE_LOCAL encoding "utf8";
\connect $DB $ROLE_LOCAL
# Create all tables and objects, and after that:
\connect $DB postgres
revoke connect on database $DB from public;
revoke all on schema public from public;
revoke all on all tables in schema public from public;
grant connect on database $DB to $ROLE_LOCAL;
grant all on schema public to $ROLE_LOCAL;
grant all on all tables in schema public to $ROLE_LOCAL;
grant all on all sequences in schema public to $ROLE_LOCAL;
grant all on all functions in schema public to $ROLE_LOCAL;
grant connect on database $DB to $ROLE_REMOTE;
grant usage on schema public to $ROLE_REMOTE;
grant select, insert, update, delete on all tables in schema public to $ROLE_REMOTE;
grant usage, select on all sequences in schema public to $ROLE_REMOTE;
grant execute on all functions in schema public to $ROLE_REMOTE;
alter default privileges for role $ROLE_LOCAL in schema public
grant all on tables to $ROLE_LOCAL;
alter default privileges for role $ROLE_LOCAL in schema public
grant all on sequences to $ROLE_LOCAL;
alter default privileges for role $ROLE_LOCAL in schema public
grant all on functions to $ROLE_LOCAL;
alter default privileges for role $ROLE_REMOTE in schema public
grant select, insert, update, delete on tables to $ROLE_REMOTE;
alter default privileges for role $ROLE_REMOTE in schema public
grant usage, select on sequences to $ROLE_REMOTE;
alter default privileges for role $ROLE_REMOTE in schema public
grant execute on functions to $ROLE_REMOTE;
# CTRL+D