274 votes

Quelle est la meilleure pratique pour gérer les mots de passe dans les dépôts git ?

J'ai un petit Bash script que j'utilise pour accéder à twitter et faire apparaître une notification Growl dans certaines situations. Quelle est la meilleure façon de gérer le stockage de mon mot de passe avec le script ?

Je voudrais commettre ce script au repo git et le rendre disponible sur GitHub, mais je me demande quelle est la meilleure façon de garder mon login/mot de passe privé tout en faisant cela. Actuellement, le mot de passe est stocké dans le script lui-même. Je ne peux pas le supprimer juste avant de pousser parce que tous les anciens commits contiendront le mot de passe. Développer sans mot de passe n'est pas une option. J'imagine que je devrais stocker le mot de passe dans un fichier de configuration externe, mais je pensais vérifier s'il existait un moyen établi de gérer cela avant d'essayer et de mettre quelque chose ensemble.

315voto

Greg Hewgill Points 356191

La façon habituelle de procéder consiste à lire les informations relatives au mot de passe à partir d'un fichier de configuration. Si votre fichier de configuration s'appelle foobar.config alors vous livrerez un fichier appelé foobar.config.example au référentiel, contenant des données d'exemple. Pour exécuter votre programme, vous devez créer un fichier local (non suivi) appelé foobar.config avec votre réel les données du mot de passe.

Pour filtrer votre mot de passe existant à partir des commits précédents, consultez la page d'aide de GitHub sur Suppression des données sensibles .

7 votes

En fait, vous pouvez ajouter un exemple de foobar.config au dépôt et ensuite ajouter foobar.config au fichier .ignore. De cette façon, l'exemple foobar.config apparaîtra lors du clonage et vos mots de passe réels ne seront pas ajoutés au répertoire.

22 votes

@Mr_Chimp : Le site .gitignore ne s'applique pas aux fichiers tracés qui sont déjà en place le dépôt. Par exemple, git add -u ajoutera un fichier modifié même s'il se trouve déjà dans .gitignore .

2 votes

En complément, voici un lien intéressant au cas où vous avez ajouté le fichier de configuration par accident et que vous souhaitez le supprimer de l'historique git : aide.github.com/articles/remove-sensitive-data

31voto

scls Points 379

Une approche peut consister à définir le mot de passe (ou la clé API) à l'aide d'une variable d'environnement. Ainsi, ce mot de passe échappe au contrôle de la révision.

Avec Bash, vous pouvez définir une variable d'environnement en utilisant

export your_env_variable='your_password'

Cette approche peut être utilisée avec des services d'intégration continue tels que Travis votre code (sans mot de passe) étant stocké dans un fichier GitHub peut être exécuté par Travis (avec votre mot de passe défini à l'aide de la variable d'environnement).

Avec Bash, vous pouvez obtenir la valeur d'une variable d'environnement en utilisant :

echo "$your_env_variable"

Avec Python, vous pouvez obtenir la valeur d'une variable d'environnement en utilisant :

import os
print(os.environ['your_env_variable'])

PS : sachez que c'est probablement un peu risqué (mais c'est une pratique assez courante). https://www.bleepingcomputer.com/news/security/javascript-packages-caught-stealing-environment-variables/

PS2 : ceci dev.to article intitulé "Comment stocker en toute sécurité les clés d'API" peut être intéressant à lire.

21voto

Prof. Falken Points 10242

Quoi Greg a dit mais j'ajouterais que c'est une bonne idée de vérifier dans un fichier foobar.config-TEMPLATE .

Il doit contenir des exemples de noms, de mots de passe ou d'autres informations de configuration. Il est alors très évident de savoir ce que le vrai foobar.config doit contenir, sans avoir à chercher dans tout le code les valeurs qui doivent être présentes dans le fichier foobar.config et quel format ils doivent avoir.

Souvent, les valeurs de configuration peuvent ne pas être évidentes, comme les chaînes de connexion à la base de données et autres choses similaires.

15voto

user3070485 Points 11

La gestion des mots de passe dans les référentiels peut être traitée de différentes manières en fonction de votre problème exact.

1. Ne le faites pas.

Et les moyens d'éviter cela sont couverts dans certaines réponses - .gitignore, config.example, etc.

ou 2. Rendre le référentiel accessible uniquement aux personnes autorisées

C'est-à-dire les personnes qui sont autorisées à connaître le mot de passe. chmod et les groupes d'utilisateurs me viennent à l'esprit, ainsi que des problèmes tels que les employés de Github ou d'AWS doivent-ils être autorisés à voir des choses si vous hébergez vos référentiels ou vos serveurs en externe ?

ou 3. Crypter les données sensibles (objet de cette réponse)

Si vous voulez stocker vos fichiers de configuration contenant des informations sensibles (comme des mots de passe) dans un endroit public, il faut les crypter. Les fichiers peuvent être décryptés lorsqu'ils sont récupérés dans le référentiel, ou même utilisés directement à partir de leur forme cryptée.

Un exemple de solution javascript pour utiliser des données de configuration cryptées est présenté ci-dessous.

const fs = require('fs');
const NodeRSA = require('node-rsa');

let privatekey = new NodeRSA();
privatekey.importKey(fs.readFileSync('private.key', 'utf8'));
const config = privatekey.decrypt(fs.readFileSync('config.RSA', 'utf8'), 'json');

console.log('decrypted: ', config);

Decrypted Config File

Vous pouvez donc récupérer un fichier de configuration crypté en écrivant seulement quelques lignes de Javascript.

Notez que mettre un fichier config.RSA dans un dépôt git en ferait effectivement un fichier binaire et perdrait ainsi beaucoup des avantages de quelque chose comme Git, par exemple la possibilité de sélectionner les modifications.

La solution pourrait être de crypter les paires clé-valeur ou peut-être seulement les valeurs. Vous pouvez crypter toutes les valeurs, par exemple si vous avez un fichier séparé pour les informations sensibles, ou crypter uniquement les valeurs sensibles si vous avez toutes les valeurs dans un seul fichier. (voir ci-dessous)

Mon exemple ci-dessus est un peu inutile pour quiconque veut faire un test avec, ou comme exemple pour commencer, car il suppose l'existence de quelques clés RSA et d'un fichier de configuration crypté. config.RSA .

Voici donc quelques lignes de code supplémentaires ajoutées pour créer des clés RSA et un fichier de configuration pour jouer avec.

const fs = require('fs');
const NodeRSA = require('node-rsa');

/////////////////////////////
// Generate some keys for testing
/////////////////////////////

const examplekey = new NodeRSA({b: 2048});

fs.writeFileSync('private.key', examplekey.exportKey('pkcs8-private'));
fs.writeFileSync('public.key', examplekey.exportKey('pkcs8-public'));

/////////////////////////////
// Do this on the Machine creating the config file
/////////////////////////////

const configToStore = {Goodbye: 'Cruel world'};

let publickey = new NodeRSA();
publickey.importKey(fs.readFileSync('public.key', 'utf8'));

fs.writeFileSync('config.RSA', publickey.encrypt(configToStore, 'base64'), 'utf8');

/////////////////////////////
// Do this on the Machine consuming the config file
/////////////////////////////

let privatekey = new NodeRSA();
privatekey.importKey(fs.readFileSync('private.key', 'utf8'));

const config = privatekey.decrypt(fs.readFileSync('config.RSA', 'utf8'), 'json');
console.log('decrypted: ', config);

Chiffrement des valeurs uniquement

fs.writeFileSync('config.RSA', JSON.stringify(config,null,2), 'utf8');

enter image description here

Vous pouvez décrypter un fichier de configuration avec des valeurs cryptées en utilisant quelque chose comme ceci.

const savedconfig = JSON.parse(fs.readFileSync('config.RSA', 'utf8'));
let config = {...savedconfig};
Object.keys(savedconfig).forEach(key => {
    config[key] = privatekey.decrypt(savedconfig[key], 'utf8');
});

Avec chaque élément de configuration sur une ligne séparée (par exemple Hello y Goodbye ci-dessus), Git reconnaîtra mieux ce qui se passe dans un fichier et stockera les modifications des éléments d'information sous forme de différences plutôt que de fichiers complets. Git sera également capable de mieux gérer les fusions, les cherry picks, etc.

Cependant, plus vous souhaitez contrôler les modifications apportées aux informations sensibles, plus vous vous orientez vers une solution de REPOSITOIRE SÛR (2) et vous éloignez d'une solution d'INFO ENCRYPTÉE (3).

4voto

El Ruso Points 1879

On peut utiliser Chambre forte HashiCorp qui sécurise, stocke et contrôle l'accès aux jetons, mots de passe, certificats, clés API, etc.

Ansible a spécifiquement une "Fonction "Vault (sans rapport avec le produit HashiCorp) pour le chiffrement des secrets au repos, également.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X