ApsaraDB RDS for PostgreSQL utilise un modèle de contrôle d'accès basé sur les rôles (RBAC) pour gérer les autorisations de base de données. Cette rubrique explique comment mettre en place un modèle d'autorisation à trois niveaux — propriétaire, rôle en lecture-écriture et rôle en lecture seule — adapté à la gestion des accès au niveau du projet ou de l'équipe.
Fonctionnement
Dans PostgreSQL, les rôles et les utilisateurs sont du même type d'objet. La distinction est fonctionnelle :
Les rôles détiennent des autorisations mais ne peuvent pas se connecter.
Les utilisateurs sont des rôles dotés de l'attribut
WITH LOGIN. Leurs autorisations effectives correspondent à leurs propres droits de connexion additionnés aux autorisations de tous les rôles qui leur sont attribués.
Lorsque vous mettez à jour les autorisations d'un rôle, tous les utilisateurs assignés à ce rôle héritent automatiquement de la modification. Aucune réattribution n'est nécessaire.
Chaque instance RDS inclut un compte privilégié nommé dbsuperuser. Ce compte dispose de toutes les autorisations sur l'instance et est réservé aux administrateurs de base de données.
Modèle d'autorisation
Le modèle à trois niveaux recommandé pour un projet ou une équipe utilise les entités suivantes :
| Entité | Type | Autorisations sur les tables | Autorisations sur les procédures stockées |
|---|---|---|---|
rdspg_owner |
Propriétaire (utilisateur avec DDL complet) | DDL (CREATE, DROP, ALTER) + DQL (SELECT) + DML (UPDATE, INSERT, DELETE) | DDL (CREATE, DROP, ALTER) + DQL (SELECT) + appel de procédures stockées |
rdspg_role_readwrite |
Rôle | DQL (SELECT) + DML (UPDATE, INSERT, DELETE) | DQL (SELECT) + appel de procédures stockées ; les opérations DDL à l'intérieur des procédures stockées renvoient une erreur d'autorisation |
rdspg_role_readonly |
Rôle | DQL (SELECT) uniquement | DQL (SELECT) + appel de procédures stockées ; les opérations DDL à l'intérieur des procédures stockées renvoient une erreur d'autorisation |
Les utilisateurs d'application héritent des autorisations via l'attribution de rôles :
rdspg_readwrite— hérite des autorisations derdspg_role_readwrite+ connexionrdspg_readonly— hérite des autorisations derdspg_role_readonly+ connexion
Pour un contrôle plus granulaire, créez des rôles supplémentaires selon vos besoins.
Ne placez pas les tables dans le schémapublic. Par défaut, tous les utilisateurs disposent de l'autorisation CREATE et de l'autorisation USAGE sur le schémapublic.
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
Une instance ApsaraDB RDS for PostgreSQL
Un accès au compte privilégié
dbsuperuserUne connexion à l'instance via un outil en ligne de commande (voir Connexion à une instance ApsaraDB RDS for PostgreSQL)
Configurer les autorisations pour un projet
L'exemple suivant configure les autorisations pour un projet nommé rdspg avec deux schémas : rdspg et rdspg_1. Exécutez toutes les commandes en tant que dbsuperuser.
Étape 1 : Créer le propriétaire et les rôles
-- Create the owner. Replace the password with a strong password.
CREATE USER rdspg_owner WITH LOGIN PASSWORD 'asdfy181BASDfadasdbfas';
-- Create the read-write and read-only roles (no login).
CREATE ROLE rdspg_role_readwrite;
CREATE ROLE rdspg_role_readonly;
-- Grant DQL + DML permissions on tables created by rdspg_owner to rdspg_role_readwrite.
ALTER DEFAULT PRIVILEGES FOR ROLE rdspg_owner GRANT ALL ON TABLES TO rdspg_role_readwrite;
-- Grant DQL + DML permissions on sequences created by rdspg_owner to rdspg_role_readwrite.
ALTER DEFAULT PRIVILEGES FOR ROLE rdspg_owner GRANT ALL ON SEQUENCES TO rdspg_role_readwrite;
-- Grant DQL-only permission on tables created by rdspg_owner to rdspg_role_readonly.
ALTER DEFAULT PRIVILEGES FOR ROLE rdspg_owner GRANT SELECT ON TABLES TO rdspg_role_readonly;
ALTER DEFAULT PRIVILEGES s'applique à tous les objets que rdspg_owner créera à l'avenir. Les objets existants nécessitent une commande GRANT distincte.
Étape 2 : Créer les utilisateurs d'application
-- Read-write user: inherits DQL + DML permissions from rdspg_role_readwrite.
CREATE USER rdspg_readwrite WITH LOGIN PASSWORD 'dfandfnapSDhf23hbEfabf';
GRANT rdspg_role_readwrite TO rdspg_readwrite;
-- Read-only user: inherits DQL-only permission from rdspg_role_readonly.
CREATE USER rdspg_readonly WITH LOGIN PASSWORD 'F89h912badSHfadsd01zlk';
GRANT rdspg_role_readonly TO rdspg_readonly;
Étape 3 : Créer un schéma et accorder l'accès
-- Set rdspg_owner as the owner of the rdspg schema.
CREATE SCHEMA rdspg AUTHORIZATION rdspg_owner;
-- Grant schema access to both roles.
GRANT USAGE ON SCHEMA rdspg TO rdspg_role_readwrite;
GRANT USAGE ON SCHEMA rdspg TO rdspg_role_readonly;
rdspg_readwriteetrdspg_readonlyhéritent de l'accès au schéma via leurs rôles. Aucune attribution directe à ces utilisateurs n'est nécessaire.
Appliquer le principe du moindre privilège
Utilisez rdspg_readonly comme utilisateur par défaut pour les connexions d'application. Basculez vers rdspg_readwrite uniquement lorsqu'une opération d'écriture est requise. Cette approche permet la séparation lecture/écriture au niveau de l'application sans la surcharge d'un intergiciel (middleware) proxy.
Si aucune instance RDS en lecture seule n'est associée à votre instance RDS, nous vous recommandons d'accorder des autorisations de lecture à un client et des autorisations de lecture et d'écriture à l'autre client. Configurez vos connexions Java Database Connectivity (JDBC) comme suit :
| Client | Utilisateur | URL JDBC |
|---|---|---|
| Client en lecture seule | rdspg_readonly |
the endpoint of read-only RDS instance 1,the endpoint of read-only RDS instance 2,the endpoint of your RDS instance |
| Client en lecture-écriture | rdspg_readwrite |
the endpoint of your RDS instance |
Étendre le modèle d'autorisation
Ajouter davantage de schémas
Pour ajouter un deuxième schéma (rdspg_1) au même projet :
CREATE SCHEMA rdspg_1 AUTHORIZATION rdspg_owner;
-- Grant the access permission on the rdspg_2 schema to roles.
-- Grant the permissions to perform DDL CREATE, DROP, and ALTER operations on tables in the rdspg_1 schema.
GRANT USAGE ON SCHEMA rdspg_1 TO rdspg_role_readwrite;
GRANT USAGE ON SCHEMA rdspg_1 TO rdspg_role_readonly;
Tous les utilisateurs assignés à ces rôles héritent automatiquement du nouvel accès au schéma.
Accorder un accès inter-projets
Pour donner à employee_readwrite (un utilisateur du projet employee) un accès en lecture au projet rdspg :
-- Grant rdspg_role_readonly permissions to employee_readwrite.
GRANT rdspg_role_readonly TO employee_readwrite;
Vérifier les autorisations
Utilisation de \du
Connectez-vous à votre instance et exécutez \du pour lister les rôles et les appartenances aux rôles :
postgres=> \du
List of roles
Role name | Attributes | Member of
------------------------+---------------+----------------------------------------------
rdspg_owner | ... | {}
rdspg_role_readwrite | Cannot login | {}
rdspg_role_readonly | Cannot login | {}
rdspg_readwrite | ... | {rdspg_role_readwrite}
rdspg_readonly | ... | {rdspg_role_readonly}
employee_readwrite | ... | {rdspg_role_readonly,employee_role_readwrite}
La colonne Member of pour employee_readwrite affiche à la fois rdspg_role_readonly et employee_role_readwrite, confirmant que l'accès en lecture inter-projets est actif.

Utilisation de SQL
Pour un audit complet de tous les rôles et de leurs appartenances :
SELECT r.rolname, r.rolsuper, r.rolinherit,
r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,
r.rolconnlimit, r.rolvaliduntil,
ARRAY(SELECT b.rolname
FROM pg_catalog.pg_auth_members m
JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)
WHERE m.member = r.oid) as memberof
, r.rolreplication
, r.rolbypassrls
FROM pg_catalog.pg_roles r
WHERE r.rolname !~ '^pg_'
ORDER BY 1;
Exemples d'autorisations
Opérations DDL par rdspg_owner
rdspg_owner détient toutes les autorisations DDL dans tout schéma dont il est propriétaire :
CREATE TABLE rdspg.test(id bigserial primary key, name text);
CREATE INDEX idx_test_name on rdspg.test(name);
Opérations DML et DQL par rdspg_readwrite
rdspg_readwrite peut lire et écrire des données, mais ne peut pas modifier le schéma :
INSERT INTO rdspg.test (name) VALUES('name0'),('name1');
SELECT id,name FROM rdspg.test LIMIT 1;
-- DDL is blocked:
CREATE TABLE rdspg.test2(id int);
ERROR: permission denied for schema rdspg
DROP TABLE rdspg.test;
ERROR: must be owner of table test
ALTER TABLE rdspg.test ADD id2 int;
ERROR: must be owner of table test
CREATE INDEX idx_test_name on rdspg.test(name);
ERROR: must be owner of table test
DQL uniquement par rdspg_readonly
rdspg_readonly peut interroger mais pas modifier les données :
INSERT INTO rdspg.test (name) VALUES('name0'),('name1');
ERROR: permission denied for table test
SELECT id,name FROM rdspg.test LIMIT 1;
id | name
----+-------
1 | name0
(1 row)