Qu'est-ce que la sécurité au niveau des lignes (RLS) ?

Mis à jour : septembre 2026

La sécurité au niveau des lignes est un mécanisme de base de données où des politiques filtrent, à chaque requête, les lignes que chacun peut voir ou modifier. Le modèle mental est celui d’une clause WHERE invisible et obligatoire : la condition que vous devriez sinon penser à écrire dans chaque requête devient une propriété de la table elle-même — appliquée par le moteur, sur chaque chemin d’accès, y compris ceux que votre code applicatif ne voit jamais.

Points clés

QuestionRéponse
Ce que c’estUn contrôle d’accès par ligne, appliqué par le moteur de base de données lui-même
Le modèle mentalUne clause WHERE impossible à oublier
Le cas d’usage phareL’isolation multi-tenant et les données par utilisateur, dans la couche qu’une faille ne peut pas sauter
Les petites lignesRôles de contournement, refus par défaut, contexte de pooling — les pièges sont opérationnels
La défaillance qu’elle éviteUn filtre oublié dans le code applicatif = une fuite entre tenants

RLS en dix lignes de SQL

CREATE TABLE invoices (
  tenant_id uuid NOT NULL,
  total     numeric(10,2)
);

ALTER TABLE invoices ENABLE ROW LEVEL SECURITY;   -- à partir d'ici : refus par défaut

CREATE POLICY tenant_isolation ON invoices
  USING      (tenant_id = current_setting('app.tenant')::uuid)   -- ce que vous pouvez lire
  WITH CHECK (tenant_id = current_setting('app.tenant')::uuid);  -- ce que vous pouvez écrire

-- Chaque requête se comporte désormais comme si elle se terminait par WHERE tenant_id = <le vôtre>.
-- Une requête qui oublie son filtre ne renvoie rien — pas tout.

La même garantie existe dans les bases de données documentaires sous la forme d’un contrôle d’accès porté par la ligne elle-même — chaque objet porte son ACL, et la plateforme l’applique à chaque requête :

// JavaScript / Node.js — Back4app JS SDK
// Row-level security as data: this row is readable by its owner, period
const note = new Parse.Object('Note');
note.set('text', 'Q3 salary planning');
note.setACL(new Parse.ACL(Parse.User.current())); // owner-only, on the row itself
await note.save();

// Later, any query by any user — the row exists only for its owner
const notes = await new Parse.Query('Note').find(); // others never see it

Ce que le moteur fait d’une requête

Comment la sécurité au niveau des lignes filtre une requêteDeux utilisateurs différents exécutent la même requête sur une même table ; le moteur applique le prédicat de la politique de sécurité ligne par ligne avant les conditions de l'utilisateur, si bien que chacun ne reçoit que les lignes que sa politique autorise.

SELECT * FROM invoices
(même requête, n'importe quel utilisateur)

Prédicat de la politique
appliqué par ligne, en premier

Le tenant A ne voit
que les lignes du tenant A

Le tenant B ne voit
que les lignes du tenant B

Deux utilisateurs différents exécutent la même requête sur une même table ; le moteur applique le prédicat de la politique de sécurité ligne par ligne avant les conditions de l'utilisateur, si bien que chacun ne reçoit que les lignes que sa politique autorise.

USING vs. WITH CHECK, permissives vs. restrictives

ConceptCe qu’il régitRègle empirique
USINGCe qui existe pour vous : les lectures, et les lignes éligibles à update/delete”Puis-je le voir ?”
WITH CHECKCe que vous pouvez écrire : les inserts, et les valeurs après update”Puis-je le créer ainsi ?”
Politiques permissives (par défaut)Combinées par OR — une seule correspondance suffitAccorder l’accès
Politiques restrictivesAjoutées par AND — toutes doivent passerImposer des limites obligatoires

Deux règles de composition à retenir de la référence PostgreSQL : omettre WITH CHECK réutilise USING pour les écritures, et au moins une politique permissive doit passer avant que les restrictives ne soient même consultées — uniquement des restrictives, et personne n’entre.

Où RLS est pris en charge

Famille de moteursMécanisme
PostgreSQL (9.5+) et dérivésCREATE POLICY — l’implémentation de référence
SQL Server (2016+)Politiques de sécurité sur des fonctions de prédicat inline (filter + block)
SQL distribué (CockroachDB, YugabyteDB)Politiques compatibles PostgreSQL
Data warehouses cloudPolitiques d’accès par ligne, à la sauce de chaque fournisseur
Bases de données documentairesPas de politiques — des ACL par objet appliquées par la couche plateforme

La dernière ligne est celle qui intéresse ce glossaire : sur les bases documentaires, la frontière au niveau des lignes est typiquement une donnée portée par la ligne (les ACL) plutôt qu’un prédicat dans le moteur — même garantie, mécanisme différent, détaillé dans l’article d’ingénierie de Back4app.

Les pièges, enfin réunis au même endroit

  • Les surprises du refus par défaut. Activer RLS sans aucune politique bloque tout le monde sauf le propriétaire — la moitié des histoires “RLS a cassé la production”, c’est ça.
  • La matrice de contournement. Les superutilisateurs, les rôles BYPASSRLS et les propriétaires de table ignorent les politiques — définissez FORCE ROW LEVEL SECURITY si le propriétaire est aussi l’utilisateur de l’application, et auditez qui détient quoi.
  • Les vues s’exécutent avec les droits de leur propriétaire par défaut — une vue sur une table sous RLS peut la contourner silencieusement, sauf si elle est créée avec les droits de l’appelant (security_invoker dans PostgreSQL).
  • Les contraintes trahissent l’existence. Une violation d’unicité ou de clé étrangère peut révéler qu’une ligne invisible existe — le canal caché documenté ; traitez l’unicité sur des valeurs protégées en conséquence.
  • Les erreurs peuvent trahir des valeurs. Des expressions conçues pour échouer sur des données précises (une division par zéro quand une valeur cachée correspond) exfiltrent via les messages d’erreur — la classe de canaux auxiliaires que décrit la documentation de SQL Server.
  • Les dumps et les pools ont des modes. Les outils de sauvegarde peuvent nécessiter de désactiver la sécurité par ligne pour tout exporter ; les poolers en mode transaction exigent un contexte à portée de transaction (SET LOCAL), sinon les tenants déteignent d’une requête à l’autre.

Performances : les politiques sont du code sur le chemin critique

Trois règles couvrent l’essentiel de l’expérience terrain : indexez chaque colonne référencée par une politique (le prédicat s’exécute avant les filtres propres à votre requête — sans index, c’est un parcours complet) ; gardez des prédicats sans jointure, en déportant les recherches dans des fonctions ou des vérifications de rôle ; et faites en sorte que les fonctions par requête soient évaluées une fois par requête, pas une fois par ligne, en les encapsulant dans une sous-requête scalaire. Bien mesurée, RLS coûte quelques points de pourcentage ; mal mesurée, c’est le ralentissement mystérieux sur chaque table que vous avez sécurisée.

Cas d’usage courants

  • SaaS multi-tenant. Le cas canonique — l’isolation des tenants appliquée sous l’application, là où un filtre oublié ne peut pas devenir une fuite.
  • Données par utilisateur. Messages, documents, dossiers médicaux : les utilisateurs voient leurs lignes, point.
  • Frontières départementales et régionales. Les commerciaux voient leur région ; les auditeurs voient tout, en lecture seule — la superposition de politiques à l’œuvre.
  • Régimes de conformité. Un contrôle d’accès démontrable au niveau de la couche de données, là où les auditeurs l’aiment.
  • Accès analytique partagé. Les analystes interrogent directement des répliques de production et ne voient que ce que leur rôle autorise — sûr parce que c’est la base de données qui l’applique, pas le dashboard.

Devriez-vous appliquer le contrôle au niveau des lignes ? Matrice de décision

Appliquez avec RLS/ACL quand…Le filtrage applicatif peut suffire quand…
Plusieurs tenants ou utilisateurs partagent des tablesLa base de données a exactement un appelant de confiance
Autre chose que l’app touche la base de donnéesAucun outil de BI, aucun SQL d’administration, aucun second service
Un filtre oublié signifie une fuite, pas un bugLe cloisonnement est une commodité, pas de la sécurité
La conformité exige une preuve au niveau des donnéesLes données ne sont pas sensibles
Vous voulez une frontière testée une fois, de façon centraliséeVous aimez auditer chaque requête pour toujours

La synthèse honnête des deux colonnes : gardez le cloisonnement dans l’application pour la lisibilité — et appliquez-le quand même dans la base de données. La défense en profondeur est tout l’enjeu.

Limites et trade-offs

  • Les politiques sont invisibles par conception — ce qui fait du débogage de “où sont passées mes lignes ?” une vraie compétence ; journalisez d’abord le contexte de session.
  • Une autorisation complexe dépasse les prédicats. Les règles qui nécessitent un état de workflow ou une logique entre entités relèvent des couches d’autorisation applicatives, avec RLS comme filet de sécurité.
  • La surface opérationnelle est réelle. La matrice de contournement, les modes de dump et le contexte de pooling sont un savoir opérationnel continu, pas une configuration ponctuelle.
  • L’évaluation par ligne est une taxe — faible quand elle est bien conçue, illimitée sinon.
  • Elle sécurise des lignes, pas des colonnes. Masquer des champs relève de la sécurité au niveau des colonnes ; combinez les deux pour un effet au niveau de la cellule.

La sécurité au niveau des lignes sur Back4app

Back4app est une plateforme open-source de Backend as a Service (BaaS) qui combine une base de données gérée, des API REST et GraphQL générées automatiquement, l’authentification, le stockage de fichiers et des fonctions serverless avec Cloud Code. Son modèle au niveau des lignes est le mécanisme d’ACL-comme-donnée des onglets ci-dessus : chaque objet porte sa liste d’accès, les rôles expriment les tenants et les équipes, et la plateforme applique les deux à chaque requêteSDK, REST, GraphQL et dashboard compris, avec les permissions au niveau de la classe comme couche restrictive par-dessus. C’est la garantie de la clause WHERE obligatoire, livrée sur une base de données documentaire, avec la liste de pièges ci-dessus absorbée par la plateforme plutôt que laissée à votre charge.

Questions fréquentes

Qu'est-ce que la sécurité au niveau des lignes, en termes simples ?

Une clause WHERE invisible et obligatoire. Vous attachez des politiques à une table, et la base de données applique automatiquement leurs conditions à chaque requête — chaque utilisateur ne voit et ne modifie que les lignes que la politique autorise, quelle que soit la requête qu'il écrit ou l'outil qu'il utilise. Le filtre vit dans la base de données : aucun chemin de code applicatif ne peut l'oublier.

Comment fonctionne la sécurité au niveau des lignes ?

Vous activez RLS sur une table et créez des politiques contenant des prédicats booléens — qui comparent typiquement la colonne de propriétaire ou de tenant d'une ligne à l'utilisateur courant ou à une variable de session. À l'exécution, le moteur évalue le prédicat ligne par ligne avant les conditions de l'utilisateur, en filtrant les lectures et en bloquant les écritures non autorisées. Une fois RLS activé sans aucune politique, le comportement par défaut est de tout refuser.

Quelle est la différence entre USING et WITH CHECK ?

Le sens. USING filtre ce qui existe pour vous : les lignes visibles par SELECT et éligibles à UPDATE ou DELETE. WITH CHECK valide ce que vous écrivez : les lignes insérées et les nouvelles valeurs après une mise à jour. Omettez WITH CHECK et le prédicat USING s'applique aux deux — mais les tables où les utilisateurs lisent largement et écrivent de façon restreinte ont besoin des deux, définis différemment.

Qui peut contourner la sécurité au niveau des lignes ?

Dans PostgreSQL : les superutilisateurs, les rôles dotés de BYPASSRLS et — celui que tout le monde oublie — le propriétaire de la table, sauf si vous définissez FORCE ROW LEVEL SECURITY. Auditer cette matrice de contournement fait partie du déploiement de RLS ; une politique parfaite ne protège rien si l'application se connecte en tant que propriétaire de la table.

La sécurité au niveau des lignes dégrade-t-elle les performances ?

Elle le peut — le prédicat de la politique est évalué sur les lignes candidates à chaque requête. Les parades sont constantes d'une expérience de production à l'autre : indexez les colonnes référencées par vos politiques, gardez des prédicats sans jointure (passez plutôt par des fonctions ou des rôles de recherche) et encapsulez les fonctions par requête pour qu'elles soient évaluées une fois par requête plutôt qu'une fois par ligne. Une politique sur une colonne non indexée, c'est un parcours complet de table avec un badge de sécurité.

Quelle est la différence entre RLS et le filtrage applicatif ?

L'endroit où vit la frontière. Le filtrage applicatif restreint les requêtes dans le code — flexible, mais dupliqué sur chaque chemin de code et contourné par tout ce qui parle directement à la base de données. RLS applique la règle dans le moteur, en couvrant chaque chemin d'accès, outils d'administration et autres services compris. Le consensus est la défense en profondeur : restreignez dans l'application pour la clarté, appliquez dans la base de données pour la sécurité.

Comment RLS fonctionne-t-il avec un pool de connexions ?

Avec précaution. Les applications qui utilisent un pool se connectent sous un seul utilisateur de base de données, donc les politiques s'appuient sur une variable de session par requête plutôt que sur l'identité de la connexion — définie à l'emprunt, lue par la politique, réinitialisée au retour. Avec les poolers en mode transaction, le paramètre doit avoir une portée de transaction, sinon le contexte d'un tenant peut fuiter vers la requête suivante sur la même connexion. Cette interaction est le bug RLS le plus fréquent en production.

Comment tester des politiques de sécurité au niveau des lignes ?

Endossez chaque rôle et exécutez les quatre opérations — select, insert, update, delete — en vérifiant à la fois ce qui apparaît et ce qui est refusé. Ajoutez les deux cas oubliés : le contexte non défini (l'absence de variable de tenant doit signifier aucune ligne, pas toutes les lignes) et la matrice de contournement (propriétaire, superutilisateur, chemins de réplication). RLS gagne votre confiance par des tests adverses, pas parce que la politique se lit bien.

Termes associés

À comparer avec

Lectures recommandées

Prêt à construire votre backend ?

Lancez votre projet sur Back4app en quelques minutes — base de données, authentification, API et Cloud Code inclus. Sans carte bancaire.

Écrit et révisé par Back4app Engineering, Back4app Engineering · Publié le 2026-09-11