Il existe quelques options pour stocker les mots de passe et autres secrets qu'un programme Python doit utiliser, en particulier un programme qui doit s'exécuter en arrière-plan où il ne peut pas simplement demander à l'utilisateur de taper le mot de passe.
Problèmes à éviter:
- Vérification du mot de passe dans le contrôle de code source où d'autres développeurs ou même le public peuvent le voir.
- D'autres utilisateurs sur le même serveur lisent le mot de passe à partir d'un fichier de configuration ou d'un code source.
- Avoir le mot de passe dans un fichier source où les autres peuvent le voir par-dessus votre épaule pendant que vous le modifiez.
Option 1: SSH
Ce n'est pas toujours une option, mais c'est probablement la meilleure. Votre clé privée n'est jamais transmise sur le réseau, SSH exécute simplement des calculs mathématiques pour prouver que vous avez la bonne clé.
Pour le faire fonctionner, vous avez besoin des éléments suivants:
- La base de données ou tout ce à quoi vous accédez doit être accessible par SSH. Essayez de rechercher «SSH» ainsi que le service auquel vous accédez. Par exemple, "ssh postgresql" . Si ce n'est pas une fonctionnalité de votre base de données, passez à l'option suivante.
- Créez un compte pour exécuter le service qui effectuera des appels à la base de données et générera une clé SSH .
- Ajoutez la clé publique au service que vous allez appeler ou créez un compte local sur ce serveur et installez-y la clé publique.
Option 2: Variables d'environnement
Celui-ci est le plus simple, donc ce pourrait être un bon point de départ. Il est bien décrit dans l'application Twelve Factor . L'idée de base est que votre code source extrait simplement le mot de passe ou d'autres secrets des variables d'environnement, puis vous configurez ces variables d'environnement sur chaque système sur lequel vous exécutez le programme. Cela peut également être une bonne idée si vous utilisez des valeurs par défaut qui fonctionneront pour la plupart des développeurs. Vous devez équilibrer cela avec le fait de rendre votre logiciel «sécurisé par défaut».
Voici un exemple qui extrait le serveur, le nom d'utilisateur et le mot de passe des variables d'environnement.
import os
server = os.getenv('MY_APP_DB_SERVER', 'localhost')
user = os.getenv('MY_APP_DB_USER', 'myapp')
password = os.getenv('MY_APP_DB_PASSWORD', '')
db_connect(server, user, password)
Recherchez comment définir les variables d'environnement dans votre système d'exploitation et envisagez d'exécuter le service sous son propre compte. De cette façon, vous n'avez pas de données sensibles dans les variables d'environnement lorsque vous exécutez des programmes dans votre propre compte. Lorsque vous configurez ces variables d'environnement, veillez à ce que les autres utilisateurs ne puissent pas les lire. Vérifiez les autorisations de fichier, par exemple. Bien sûr, tous les utilisateurs avec l'autorisation root pourront les lire, mais cela ne peut pas être aidé.
Option 3: fichiers de configuration
Ceci est très similaire aux variables d'environnement, mais vous lisez les secrets à partir d'un fichier texte. Je trouve toujours les variables d'environnement plus flexibles pour des choses comme les outils de déploiement et les serveurs d'intégration continue. Si vous décidez d'utiliser un fichier de configuration, Python prend en charge plusieurs formats dans la bibliothèque standard, tels que JSON , INI , netrc et XML . Vous pouvez également trouver des packages externes comme PyYAML et TOML . Personnellement, je trouve JSON et YAML les plus simples à utiliser, et YAML autorise les commentaires.
Trois choses à considérer avec les fichiers de configuration:
- Où est le fichier? Peut-être un emplacement par défaut comme
~/.my_app
, et une option de ligne de commande pour utiliser un emplacement différent.
- Assurez-vous que les autres utilisateurs ne peuvent pas lire le fichier.
- Évidemment, ne validez pas le fichier de configuration dans le code source. Vous souhaiterez peut-être valider un modèle que les utilisateurs peuvent copier dans leur répertoire de base.
Option 4: module Python
Certains projets mettent simplement leurs secrets directement dans un module Python.
# settings.py
db_server = 'dbhost1'
db_user = 'my_app'
db_password = 'correcthorsebatterystaple'
Importez ensuite ce module pour obtenir les valeurs.
# my_app.py
from settings import db_server, db_user, db_password
db_connect(db_server, db_user, db_password)
Un projet qui utilise cette technique est Django . Évidemment, vous ne devriez pas vous engager settings.py
dans le contrôle de code source, bien que vous souhaitiez peut-être valider un fichier appelé settings_template.py
que les utilisateurs peuvent copier et modifier.
Je vois quelques problèmes avec cette technique:
- Les développeurs peuvent commettre accidentellement le fichier dans le contrôle de code source. L'ajouter à
.gitignore
réduit ce risque.
- Une partie de votre code n'est pas sous contrôle de code source. Si vous êtes discipliné et ne mettez que des chaînes et des nombres ici, ce ne sera pas un problème. Si vous commencez à écrire des classes de filtres de journalisation ici, arrêtez!
Si votre projet utilise déjà cette technique, il est facile de passer aux variables d'environnement. Déplacez simplement toutes les valeurs de paramètre vers des variables d'environnement et changez le module Python pour lire à partir de ces variables d'environnement.