Sur beaucoup d'instances ServiceNow, la visibilité au niveau des enregistrements repose encore sur des business rules Before Query écrites il y a des années : un script qui ajoute une condition à chaque requête sur une table pour que chaque utilisateur ne voie que ce qu'il doit voir. Elles fonctionnent, et c'est précisément pour cela que personne n'ose y toucher.
Depuis les versions Xanadu et Yokohama, ServiceNow propose un mécanisme conçu exactement pour ce rôle : les Security Data Filters. L'éditeur les présente comme une alternative aux business rules Before Query, qui applique les protections directement dans les requêtes en base.
Passer de l'un à l'autre n'a pourtant rien d'un simple remplacement. Certaines règles y gagnent beaucoup, d'autres ne peuvent pas migrer du tout, et une migration menée à la légère peut exposer des données que vous pensiez protégées. Cet article fait le point sur les gains, sur les pièges, et sur la manière de migrer sans risque.
Pourquoi les Before Query sont une dette
Une business rule Before Query s'exécute avant la requête en base et lui ajoute des conditions. Elle n'a jamais été pensée comme un outil de sécurité : c'est un point d'accroche générique pour du script, que les équipes ont détourné pour cloisonner les données. La documentation ServiceNow demande de ne les utiliser qu'en cas de nécessité, prévient qu'un trop grand nombre de ces règles dégrade les performances de l'instance, et recommande de limiter les clauses OR et les recherches sur des champs non indexés.
Sur le terrain, trois problèmes reviennent presque partout :
Elles filtrent aussi les GlideRecord côté serveur. Une règle écrite pour les listes peut modifier en silence ce que voient les jobs planifiés, les flows ou les intégrations, sauf si chaque règle porte le bon garde-fou.
C'est du code. Chaque règle embarque sa propre logique, appelle souvent des Script Includes, et doit être relue, testée et maintenue comme n'importe quel script.
Elles sont difficiles à diagnostiquer. Le débogage des ACL ne les signale pas : un utilisateur à qui il manque des enregistrements peut lancer toute une équipe sur une fausse piste.
Une règle typique ressemble à ceci :
(function executeRule(current, previous) {
// Only filter interactive sessions, never background scripts
if (!gs.getSession().isInteractive() || gs.hasRole('admin'))
return;
// Agents only see incidents assigned to one of their groups
current.addQuery('assignment_group', gs.getUser().getMyGroups());
})(current, previous);Le test isInteractive est la seule chose qui tient cette règle à l'écart des traitements en arrière-plan. Il suffit de l'oublier une fois pour que vos automatisations soient filtrées elles aussi.
Ce que changent les Security Data Filters
Un Security Data Filter est un enregistrement déclaratif, géré dans System Security par les personnes qui détiennent le rôle security_admin. Il associe une table, une condition construite avec le constructeur de conditions, et un security attribute qui détermine à qui le filtre s'applique, en mode If ou Unless. La règle ci-dessus devient un filtre sur la table Incident avec la condition « Assignment group est l'un de mes groupes », appliqué sauf si l'utilisateur possède le rôle admin.
Quand une requête atteint la table, la plateforme ajoute la condition à la requête SQL elle-même : les lignes interdites ne sortent jamais de la base. Plusieurs filtres sur une même table se combinent par un ET. Comme une business rule Before Query, un filtre fait aussi disparaître des listes le message « lignes retirées par des contraintes de sécurité », puisque les lignes non autorisées ne sont jamais lues.
Le vrai changement de comportement porte sur le périmètre. Par défaut, les filtres s'appliquent aux requêtes GlideRecordSecure, GlideRecordSandbox et GlideAggregateSandbox. Un script côté serveur peut les activer ou les désactiver explicitement avec enableSecurityFeature et disableSecurityFeature, mais un GlideRecord classique n'est pas filtré tant que vous ne le demandez pas.
Les gains concrets d'une migration
Une fonctionnalité conçue pour la sécurité. Un employé de ServiceNow explique que les Security Data Filters font officiellement partie de l'architecture de sécurité de la plateforme et passent par une assurance qualité bien plus poussée que les business rules Before Query, qui n'ont jamais été construites pour cet usage.
La sécurité reste à sa place. Comme un GlideRecord classique n'est pas filtré par défaut, un filtre ne déborde plus sur les jobs planifiés, les flows et les intégrations. Plus besoin de penser au test isInteractive.
Des règles déclaratives et auditables. Une condition et un security attribute se lisent par un auditeur ou un architecte sans ouvrir d'éditeur de script.
Des security attributes réutilisables. Un même attribut peut piloter plusieurs filtres et ACL : la définition de « qui est exempté » se trouve à un seul endroit.
Une performance mesurable. L'outil d'analyse de performance exécute une requête type avec et sans le filtre, puis classe l'impact sur le temps d'exécution médian en Low, Medium ou Critical, avant toute mise en production.
Les règles à ne pas migrer telles quelles
Toutes les business rules Before Query ne sont pas de bonnes candidates. Quatre cas méritent un second examen avant toute réécriture.
Une logique OU répartie sur plusieurs règles. Plusieurs filtres sur une même table se combinent par un ET, alors que les business rules Before Query peuvent construire des conditions OU, y compris avec l'opérateur ^NQ. Un ensemble de règles qui ouvrent chacune l'accès à une population différente ne se traduit pas en un filtre par règle : il faut le repenser en une seule condition.
Une logique très scriptée. Quand l'accès dépend de valeurs calculées, comme une chaîne hiérarchique parcourue dans un Script Include, le constructeur de conditions ne sait pas toujours l'exprimer. Un security attribute peut contenir un script, mais celui-ci évalue le contexte de l'utilisateur, pas l'enregistrement.
Des contournements de la séparation des domaines. Si la règle compense un cloisonnement sur une instance de fournisseur de services, regardez d'abord le plugin Domain Separation. ServiceNow indique que les business rules Before Query ne le remplacent pas.
Des règles qui ne relèvent pas de la sécurité. Filtrer une liste par confort est une question de visibilité. La documentation appelle à la prudence quand on utilise des data filters comme contrôles de visibilité.
Les pièges après la migration
La migration modifie des comportements que des tests centrés sur les listes ne détecteront pas.
Le code spécifique qui comptait sur l'ancienne règle. Les Script Includes derrière les widgets de portail, les UI pages ou les API REST scriptées interrogent souvent avec un GlideRecord classique et s'appuyaient sans le dire sur la business rule Before Query. Après la bascule, ils renvoient des données non filtrées. ServiceNow recommande d'activer explicitement les data filters pour les requêtes exposées aux utilisateurs qui n'utilisent pas GlideRecordSecure.
Les tables parentes. Un filtre posé sur une table enfant ne s'applique pas quand les données sont lues via la table parente. Un filtre sur Incident se contourne en ouvrant une liste Task filtrée sur les incidents. Posez un filtre sur les deux tables.
Les requêtes indirectes. Un guide communautaire rédigé par un employé de ServiceNow décrit comment un rapport en liste sur les Affected CIs peut afficher des champs de tâches protégées lorsque le rapport ne pose aucune condition sur la table Task elle-même.
La performance. Chaque requête sur la table porte la condition supplémentaire. Les colonnes non indexées, les conditions nombreuses et les opérateurs comme contains sont les causes habituelles de listes lentes.
C'est pourquoi ce même guide sur le besoin d'en connaître recommande de combiner les Security Data Filters avec des ACL Deny-Unless : chaque mécanisme couvre les angles morts de l'autre.
Une méthode de migration en cinq étapes
Inventorier. Listez les business rules actives dont l'action Query est cochée (requête encodée
action_query=true^active=truesursys_script). Pour chacune, notez la table, la condition, l'objectif, qui est exempté, et si elle se limite aux sessions interactives.Classer. Séparez les règles de sécurité des règles de confort, les conditions que le constructeur sait exprimer des logiques à base de OU ou très scriptées, et les règles liées à la séparation des domaines.
Traduire. Créez un filtre inactif par règle éligible, privilégiez les conditions dynamiques comme « est l'un de mes groupes » plutôt que des valeurs codées en dur, et exprimez les exemptions avec un security attribute en mode Unless.
Mesurer et tester. Passez l'outil d'analyse de performance sur des requêtes réalistes. Sur une instance hors production, testez chaque profil dans les listes, formulaires, workspaces, portail, rapports, exports et l'API REST Table, y compris les accès par table parente et par référence indirecte. Vérifiez que les jobs planifiés et les intégrations voient toujours ce qu'ils doivent voir.
Basculer. Activez le filtre et désactivez la business rule plutôt que de la supprimer. Convertissez en GlideRecordSecure les requêtes GlideRecord exposées aux utilisateurs repérées à l'étape 4, surveillez, puis retirez l'ancienne règle.
À retenir
Migrer vers les Security Data Filters vaut la peine pour les règles dont l'objectif est la sécurité et dont la logique tient dans une condition : vous gagnez un mécanisme conçu pour cet usage, une gouvernance lisible et un moyen intégré de mesurer la performance.
Ce n'est pas une réécriture mécanique. Les règles à base de OU ou très scriptées devront parfois rester en place ou être repensées, et le changement de comportement par défaut sur GlideRecord doit être traité explicitement. Menez la migration comme un projet de sécurité : inventorier, classer, tester chaque chemin d'accès, puis basculer.



