Protection des secrets à l’aide des fonctionnalités de la plate-forme
Objectifs de formation
Une fois cette unité terminée, vous pourrez :
- Énumérer les options et les bonnes pratiques de stockage des secrets dans les packages gérés.
- Créer des identifiants nommés pour définir de manière sécurisée des points de terminaison d’appel et les paramètres d’authentification associés
- Décrire comment des paramètres personnalisés protégés et des champs d’API de métadonnées peuvent être utilisés pour stocker les secrets
Stocker les secrets d’applications dans Salesforce.
Dans l’unité précédente, vous avez appris comment identifier les secrets et les personnes qui doivent pouvoir y accéder. La prochaine étape consiste à apprendre comment les protéger.
Salesforce Platform dispose de différentes fonctionnalités qui peuvent être utilisées pour stocker les secrets.
- Les identifiants nommés
- Les paramètres personnalisés (protégés, non protégés, gérés et non gérés)
- Les types de métadonnées personnalisés
Dans cette unité, vous apprendrez comment chacune de ces options peut permettre de stocker des secrets, afin que vous puissiez vous assurer que les informations sensibles sont bien contrôlées.
Identifiants nommés
Les identifiants nommés constituent un mécanisme permettant de gérer en toute sécurité les valeurs d’authentification pour les fournisseurs et les services externes. Ils fournissent des processus d’implémentation d’authentification standard dans un ensemble d’entités sécurisées et gérables. Salesforce gère toute l’authentification des appels Apex qui spécifie un identifiant nommé comme point de terminaison d’appel, et vous n’avez pas besoin d’ajouter de logique d’authentification supplémentaire à votre code Apex. Les identifiants nommés peuvent être définis de manière à permettre une mise en place sécurisée et pratique de ces types d’appels. Une fois qu’ils sont créés, vous pouvez remplacer dans votre code les références codées en dur à des URL par des références aux identifiants nommés, ce qui produit un code plus propre, plus simple et plus sécurisé.
Les identifiants nommés sont utiles pour définir des points de terminaison d’appel référencés dans un package géré. Sans eux, pour mettre en place un appel authentifié, le développeur doit effectuer les tâches supplémentaires suivantes.
- référencer l’URL comme point de terminaison d’appel ;
- enregistrer l’URL dans vos paramètres de site distant ;
- ajouter du code personnalisé pour effectuer les éventuelles tâches d’authentification associées.
Imaginons par exemple que vous avez une application qui se connecte régulièrement à un service externe pour récupérer des données. Cependant, ce service externe exige que toutes les requêtes incluent une clé d’API pour être authentifiées. Souvent, les développeurs remplissent cette exigence en codant la clé en dur dans le code source pour pouvoir l’utiliser à chaque requête. Prenons l’exemple de code suivant.
String key = ’supersecurepassword’; HttpRequest req = new HttpRequest(); req.setEndpoint(’https://www.example.com/test?APIKEY=’+key); req.setMethod(’GET’); Http http = new Http(); HTTPResponse res = http.send(req); return res.getBody();
Coder les secrets en dur est certainement une solution simple, mais cette approche présente trois problèmes principaux.
- Toute personne qui peut voir le code source peut également voir les secrets qu’il contient.
- Si un secret est mis à jour, vous devez modifier toutes ses occurrences dans le code source.
- Assurer la portabilité de ce secret entre différentes applications peut créer d’autres complications.
Les identifiants nommés à la rescousse ! Plutôt que de coder en dur la valeur dans votre code, vous pouvez utiliser des identifiants nommés pour stocker les secrets. Cette méthode vous permet de faire référence aux identifiants nommés pour accéder à la valeur secrète, comme s’il s’agissait de n’importe quelle autre variable de votre code.
Avantages des identifiants nommés
En plus de permettre de limiter l’accès aux secrets de votre application, les identifiants nommés facilitent grandement la maintenance des secrets. Une fois l’identifiant nommé configuré, vous pouvez le changer facilement chaque fois que nécessaire en le modifiant dans vos paramètres. Toutes les instances de votre code faisant référence au secret contiennent toujours des valeurs à jour, puisqu’elles font directement référence à l’identifiant nommé.
Utilisation appropriée des identifiants nommés
Bien que les identifiants nommés soient relativement simples à configurer, ils ne sont pas forcément la bonne solution à tous les cas d’utilisation. Ils sont bien adaptés aux protocoles d’authentification standard, par nom et mot de passe, OAuth 2.0, Signature AWS Version 4 et JWT signés.
Les identifiants nommés sont conçus pour faciliter le travail et la sécurité des administrateurs et développeurs de votre organisation. Néanmoins, ils ne constituent pas toujours le meilleur choix. Étant donné que les utilisateurs disposant des autorisations Modify All Data (Modifier toutes les données) ou Author Apex (Auteur Apex) peuvent modifier ou appeler un identifiant nommé, ils peuvent également accéder aux données protégées par l’identifiant nommé. Ils peuvent peut-être même extraire l’identifiant et le mot de passe. Si vous devez tenir compte de ces cas d’utilisation, par exemple un éditeur de logiciels indépendant qui crée un package devant communiquer avec des services Cloud de manière privée, alors vous pouvez envisager d’autres options telles que les paramètres personnalisés protégés et gérés ou les types de métadonnées personnalisés protégés et gérés. Lisez la prochaine section pour en savoir plus sur ces options.
Nouvelle fonctionnalité d’identifiants nommés/externes
La nouvelle fonctionnalité d’identifiants nommés/externes dans Salesforce est conçue pour améliorer la sécurité et rationaliser les intégrations externes. Les identifiants externes représentent les détails de la manière dont Salesforce s’authentifie auprès d’un système externe à l’aide d’un protocole d’authentification, établissant un lien vers des ensembles d’autorisations, des profils et des en-têtes personnalisés facultatifs. Les utilisateurs disposant des autorisations nécessaires peuvent afficher, créer, modifier et supprimer des identifiants externes.
Les identifiants nommés agissent comme des connexions logiques aux systèmes externes, éliminant ainsi le besoin d’intégrer des URL physiques dans le code Apex et de gérer les jetons d’authentification dans des magasins de données non chiffrés. Ils spécifient l’URL d’un point de terminaison d’appel et de ses paramètres d’authentification exigés en une seule définition. Les identifiants nommés prennent en charge différents types, notamment SecuredEndpoint, PrivateEndpoint et Legacy (obsolète).
Les interactions entre les identifiants nommés et les identifiants externes impliquent d’abord de créer un identifiant externe, en spécifiant le protocole d’authentification et l’ensemble d’autorisations ou le profil. Ensuite, un identifiant nommé est créé, servant de point de terminaison d’appel pour les services externes. Les détails d’authentification de l’identifiant externe sont liés à l’identifiant nommé, permettant des appels sécurisés et authentifiés.
Les ensembles d’autorisations jouent un rôle crucial dans le contrôle de l’accès aux services externes. Les informations d’identification externes permettent d’authentifier les utilisateurs, tandis que les ensembles d’autorisations permettent de leur attribuer des autorisations. Les principaux dans les identifiants externes sont mappés avec les autorisations utilisateur, garantissant que les utilisateurs disposent de l’autorisation nécessaire avant d’accéder aux systèmes distants. Les identifiants externes des utilisateurs stockent des jetons chiffrés, offrant ainsi un moyen sécurisé de gérer l’authentification propre à l’utilisateur.
Il est possible d’ajouter des en-têtes personnalisés aux identifiants nommés et aux identifiants externes, permettant aux appels Salesforce vers des systèmes distants d’inclure les paramètres personnalisés nécessaires pour répondre aux demandes. Cette personnalisation améliore la flexibilité et s’applique à divers cas d’utilisation et exigences de sécurité.
Salesforce Platform recommande de créer et de modifier des identifiants nommés et externes via l’interface utilisateur de Salesforce, bien que cela soit également possible via les API REST Metadata, Tooling et Connect. Dans l’ensemble, la fonctionnalité d’identifiants nommés/externes offre une approche robuste et personnalisable pour gérer les intégrations externes sécurisées et authentifiées.
Secrets distribués sécurisés
Les identifiants nommés sont parfaits pour les appels à des services externes dans une organisation où les administrateurs peuvent accéder aux secrets d’authentification associés. Mais comment faire lorsque vous devez empêcher les administrateurs de voir les données, ou lorsque vous voulez distribuer les secrets sur plusieurs organisations Salesforce ?
Dans ce type de situation, le code doit être déployé comme package géré. Vous pouvez facilement lancer une organisation Developer Edition gratuite pour servir d’organisation d’empaquetage à votre code. Si vous êtes un partenaire AppExchange, vous pouvez créer des organisations Developer Edition depuis votre plate-forme d’environnement. Vous pouvez également vous rendre sur la page d’inscription à Developer Edition. Dans votre organisation d’empaquetage, vous pouvez rassembler des classes Apex, des déclencheurs Apex, des objets Salesforce et d’autres formes courantes de métadonnées dans un package géré qui pourra être facilement déployé vers toute autre instance ou organisation Salesforce. Vous pouvez vous représenter un package géré comme une version plus complexe d’un fichier zip.
Du point de vue de la sécurité, l’utilisation des packages gérés (par opposition aux packages non gérés ou au code non empaqueté) a de nombreux avantages.
- Les packages gérés possèdent les fonctionnalités nécessaires pour pousser les mises à jour automatiques, les patchs et les correctifs si des vulnérabilités de sécurité sont détectées.
- Leur code source est masqué (sauf dans le cas de classes Apex globales explicitement exposées), ce qui signifie que leur logique métier ou programmatique fondamentale ne peut pas être altérée, cassée par inadvertance, ou modifiée de manière malveillante et redistribuée. Le code masqué empêche également que les secrets contenus dans le package ne soient visibles.
- Comme vous devrez définir un espace de noms unique pour votre package géré, il n’y aura pas de conflit d’espace de noms. Il permet également de séparer votre package de l’espace de noms local, ce qui améliore encore la protection des secrets qu’il contient. Par défaut, les secrets des packages ne sont pas accessibles par le code exécuté en dehors d’un package géré.
Gestion des paramètres personnalisés protégés et des types de métadonnées personnalisés
Rassembler votre code dans un package géré a de nombreux avantages en termes de sécurité, et vous permet aussi d’accéder à deux autres fonctionnalités de stockage et de distribution de l’information : les paramètres personnalisés protégés et les métadonnées personnalisées protégées.
Les paramètres personnalisés peuvent permettre de stocker pratiquement n’importe quel type de données et sont extrêmement flexibles en matière d’utilisations et de contenus potentiels. En bref, les paramètres personnalisés permettent de créer des ensembles de données personnalisés exposés au cache de l’application, ce qui évite de répéter les mêmes requêtes à la base de données et améliore l’efficacité de votre application. Par exemple, un paramètre personnalisé peut être utilisé pour stocker un ensemble de données utilisé pour personnaliser les expériences utilisateur au sein d’une application. Ou un paramètre personnalisé peut être créé pour stocker une liste de noms de produits référencés sur de nombreuses pages, afin d’offrir un accès rapide et facile. En ce qui concerne la sécurité de l’application, les paramètres personnalisés peuvent être utilisés pour stocker des informations sensibles ou des secrets.
Les paramètres personnalisés peuvent avoir différents niveaux de visibilité. Un paramètre personnalisé protégé contenu dans un package géré n’est pas visible par les organisations abonnées via Apex ou l’API, ce qui en fait un bon endroit pour stocker certains types de secrets. Les paramètres personnalisés dont la visibilité est définie comme publique ou contenus dans un package non géré sont visibles par le WSDL (Web Service Description Language) de l’entreprise. Par conséquent, il est important que les paramètres personnalisés protégés se trouvent dans un package géré lorsqu’ils contiennent des informations sensibles.
Les champs de métadonnées personnalisés peuvent être utilisés pour stocker des secrets de manière semblable aux paramètres personnalisés. Pour assurer correctement leur confidentialité, définissez leur visibilité sur Protected (Protégé) et placez-les dans un package géré. Les champs d’API de métadonnées personnalisés et protégés sont un excellent endroit pour stocker les clés d’API ou d’autres clés secrètes, par exemple.
Du point de vue des paramètres de visibilité, les paramètres personnalisés et les champs de métadonnées disposent de différentes options.
- Public (local)
- Protégé (local)
- Public (géré)
- Protégé (géré)
Si les trois premières options sont viables pour stocker des données en général, toute personne dans l’organisation peut voir les valeurs des données si vous utilisez ces paramètres. Ne les utilisez que si vous stockez des données accessibles publiquement. Pour les données sensibles, par exemple les secrets des applications, choisissez l’option protégé et géré.
La possibilité de limiter la visibilité, la simplicité d’accès et les fonctionnalités de cache font des paramètres et des champs de métadonnées personnalisés des options viables et attractives pour stocker les secrets.
Création de paramètres personnalisés protégés et gérés
Vous pouvez créer un paramètre personnalisé protégé et géré nommé Secrets du district qui pourra être utilisé pour stocker les secrets de manière sécurisée. Créez un paramètre personnalisé protégé dans Setup (Configuration) en accédant à Quick Find (Recherche rapide), Custom Settings (Paramètres personnalisés), puis en cliquant sur New (Nouveau). Définissez une étiquette, un nom d’objet, un type de paramètre et une visibilité (définissez-la comme Protégée). Une fois que vous aurez cliqué sur Enregistrer, vous serez prêt à ajouter des champs personnalisés pour stocker les secrets.
Enfin, entrez vos secrets dans vos champs personnalisés protégés. Comme seules les définitions de paramètre sont incluses dans le package, vous aurez besoin d’Apex ou d’un script d’API qui remplira les secrets pour vous une fois le package installé sur l’organisation cible ou abonnée.
Utilisation des paramètres personnalisés protégés et gérés
Vous pouvez référencer des paramètres personnalisés de la même manière que vous référenceriez des objets personnalisés. Pour accéder à des paramètres personnalisés, vous pouvez utiliser des champs de formules, des méthodes de paramètres personnalisés Apex, l’API SOAP, des règles de validation, des flux, etc. Les références à un paramètre personnalisé protégé ne peuvent être faites qu’au sein du même package géré (c’est-à-dire dans un même espace de noms). Parmi les méthodes Apex les plus courantes pour référencer des paramètres personnalisés, on trouve :
-
getInstance()
-
getInstance(userId)
-
getInstance(profileId)
-
getOrgDefaults()
-
getValues(userId)
-
getValues(profileId)
Voici un exemple qui utilise getInstance()
pour accéder aux secrets stockés sous forme de composant de paramètre personnalisé.
CustomSettingName__c cmcs=CustomSettingName__c.getInstance();
Types de métadonnées personnalisés
Les types de métadonnées personnalisés protégés peuvent également être définis pour contenir des secrets, de la même manière qu’il est possible de définir des paramètres personnalisés. Ces types de métadonnées personnalisés doivent être conçus afin d’être inclus dans un package géré pour être efficacement masqués et protégés. La différence principale est que les données contenues dans les types de métadonnées personnalisés correspondent aux métadonnées de votre application.
C’est souvent un avantage. Imaginez que vous êtes un développeur créant une nouvelle application dans votre organisation d’empaquetage Developer Edition. Cette application a de nombreuses fonctionnalités pratiques, notamment une intégration avec l’API externe d’example.com. Pour faire des appels à example.com, vous devez stocker la clé d’API quelque part. L’une des options est de stocker la clé d’API secrète dans un champ personnalisé. Procéder ainsi fonctionnera bien dans votre propre organisation DE, mais quelque chose ne va pas dans cette approche.
Au-delà d’être une solution non sécurisée, le stockage de la clé d’API secrète dans un champ personnalisé pose un problème lors du redéploiement. Lorsque vous essaierez de déplacer l’ensemble de votre code et de vos personnalisations vers votre organisation de production, la valeur de votre clé secrète ne sera pas poussée simultanément. Vos données ne sont pas déplacées en production avec votre ensemble de modifications. Vous devrez insérer la valeur de la clé manuellement dans le champ, ou vous écrire un script qui la renseignera pour vous. Avec un type de métadonnées personnalisé, à l’inverse, votre clé d’API secrète sera traitée comme n’importe quelle autre personnalisation et déplacée en production. Dans ce scénario, vous n’avez donc pas besoin de l’y insérer vous-même.
N’oubliez pas que pour charger des données dans un paramètre personnalisé, vous devez écrire un script à exécuter après l’installation. Mais ce n’est pas la peine d’écrire de script pour les types de métadonnées personnalisés protégés. Les données contenues dans un type de métadonnées personnalisé sont disponibles sous forme de métadonnées séparées que vous pourrez ajouter à votre package. Extrêmement pratique, n’est-ce pas ?
L’une des caractéristiques les plus intéressantes des types de métadonnées personnalisés est que vous pouvez y accéder grâce à SOQL, comme pour n’importe quel objet personnalisé. La seule différence est que les types de métadonnées ont un suffixe en __mdt
au lieu de __c
. Si vous aviez besoin de sélectionner un type de métadonnées personnalisé, votre requête ressemblerait donc à ceci :
SELECT Teacher__c, Coach__c, Counselor__c , Administrator__c FROM District_Profiles__mdt
Cette ligne récupère toutes les valeurs de District_Profiles__mdt
. Plutôt simple, non ?
Comparaison entre paramètres personnalisés et types de métadonnées personnalisés
Vous pouvez utiliser soit les paramètres personnalisés, soit les types de métadonnées personnalisés pour sécuriser vos secrets, mais il y a des différences notables entre les deux. Voyons à quel moment utiliser chacun.
Utilisez les paramètres personnalisés protégés si :
- Le secret doit être mis à jour fréquemment et disponible immédiatement. Étant donné que les types de métadonnées doivent être mis en file d’attente et déployés, les secrets mis à jour dans les types de métadonnées ne sont pas disponibles immédiatement. Dans ce cas, un paramètre personnalisé est la meilleure option.
- Vous souhaitez spécifier les profils et utilisateurs qui peuvent accéder à chaque secret. Les types de métadonnées n’offrent pas le même degré de précision que les types de hiérarchies des paramètres personnalisés, qui vous permettent de spécifier pour quels profils ou utilisateurs les secrets doivent être disponibles. Il vaut donc mieux utiliser un paramètre personnalisé.
Utilisez un type de métadonnées personnalisé si :
- Vous voulez déployer un secret partagé sans étapes de configuration complémentaires.
- Les secrets dans des métadonnées personnalisées sont faciles à migrer, par exemple depuis une sandbox ou un environnement de développement vers un environnement de production. Cependant, avec les paramètres personnalisés, les administrateurs doivent soit écrire des scripts à exécuter après l’installation, soit créer des pages pour entrer manuellement et stocker les secrets dans le nouvel environnement.
Ressources
-
Blog des développeurs Salesforce : Apex Developer Guide: Named Credentials as Callout Endpoints
-
Blog des développeurs Salesforce : Comment utiliser les types de métadonnées personnalisés pour économiser des années de développement sur les configurations d’applications
-
Blog des développeurs Salesforce : Apex Developer Guide: Custom Settings Methods
-
Aide Salesforce : Définition de paramètres personnalisés