web-dev-qa-db-fra.com

Une stratégie pour garder les informations secrètes telles que les clés API hors du contrôle des sources?

Je travaille sur un site Web qui permettra aux utilisateurs de se connecter en utilisant OAuth informations d'identification de Twitter, Google, etc. Pour ce faire, je dois m'inscrire auprès de ces différents fournisseurs et obtenir une clé API super secrète que je dois protéger avec des engagements contre diverses parties du corps. Si ma clé est gankée, la partie est arrachée.

La clé API doit voyager avec ma source, car elle est utilisée au moment de l'exécution pour effectuer des demandes d'authentification. Dans mon cas, la clé doit exister dans l'application dans un fichier de configuration ou dans le code lui-même. Ce n'est pas un problème lorsque je crée et publie à partir d'une seule machine. Cependant, lorsque nous ajoutons le contrôle de source dans le mixage, les choses se compliquent.

Comme je suis un salaud pas cher, je préférerais de loin utiliser des services de contrôle de source gratuits tels que TFS dans le cloud ou GitHub. Cela me laisse avec une légère énigme:

Comment puis-je garder mon corps intact lorsque mes clés API sont dans mon code et que mon code est disponible dans un référentiel public?

Je peux penser à un certain nombre de façons de gérer cela, mais aucune n'est satisfaisante.

  • Je pourrais supprimer toutes les informations privées du code et les modifier à nouveau après le déploiement. Ce serait une douleur sévère à mettre en œuvre (je ne détaillerai pas les nombreuses façons), et ce n'est pas une option.
  • Je pourrais le crypter. Mais comme je dois le décrypter, n'importe qui avec la source pourrait comprendre comment le faire. Inutile.
  • Je pourrais payer pour le contrôle des sources privées. LOL j/k dépenser de l'argent? S'il vous plaît.
  • Je pourrais utiliser les fonctionnalités du langage pour séparer les informations sensibles du reste de ma source et donc les garder du contrôle des sources. C'est ce que je fais maintenant, mais cela pourrait facilement être foiré en archivant par erreur le fichier secret.

Je suis vraiment à la recherche d'un moyen garanti de ne pas partager mes informations privées avec le monde (sauf sur snapchat) qui fonctionnera sans heurts lors du développement, du débogage et du déploiement et sera également infaillible. C'est complètement irréaliste. Alors, que puis-je faire de façon réaliste?

Détails techniques: VS2012, C # 4.5, le contrôle de code source sera soit le service TF, soit GitHub. Utilise actuellement une classe partielle pour diviser les clés sensibles dans un fichier .cs distinct qui ne sera pas ajouté au contrôle de code source. Je pense que GitHub peut avoir l'avantage car .gitignore pourrait être utilisé pour s'assurer que le fichier de classe partiel n'est pas archivé, mais je l'ai déjà foutu avant. J'espère un "oh, problème commun, c'est comme ça que vous le faites" mais je devrai peut-être me contenter de "qui ne craint pas autant qu'il aurait pu",: /

219
Ripped Off

Ne mettez pas vos informations secrètes dans votre code. Mettez-le dans un fichier de configuration qui est lu par votre code au démarrage. Les fichiers de configuration ne doivent pas être placés sur le contrôle de version, à moins qu'il ne s'agisse des "valeurs par défaut d'usine", et ils ne doivent donc pas contenir d'informations privées.

Voir aussi la question Contrôle de version et fichier de configuration personnel pour savoir comment bien faire.

130
Philipp

Vous pouvez mettre toutes les clés privées/protégées comme variables d'environnement système. Votre fichier de configuration ressemblera à ceci:

private.key=#{systemEnvironment['PRIVATE_KEY']}

C'est ainsi que nous traitons ces cas et rien ne va dans le code. Il fonctionne très bien combiné avec différents fichiers de propriétés et profils. Nous utilisons différents fichiers de propriétés pour différents environnements. Dans notre environnement de développement local, nous mettons les clés de développement dans les fichiers de propriétés pour simplifier la configuration locale:

private.key=A_DEVELOPMENT_LONG_KEY
29
Ioannis Tzikas

Voie Pure Git

  • .gitignore fichier inclus avec données privées
  • Utilisez une branche locale, dans laquelle vous remplacez TEMPLATE par DATA
  • Utilisez des filtres de maculage/nettoyage, dans lesquels le script du filtre (local) effectue un remplacement bidirectionnel TEMPLATE <-> DATA

Voie mercurielle

  • MQ-patch (s) au-dessus du code factice, qui remplace TEMPLATE par DATA (les changements sont publics, le patch est privé)
  • Extension de mots clés avec des mots clés spécialement conçus (développé uniquement dans votre répertoire de travail)

Manière agnostique SCM

  • Faire remplacer les mots clés dans le cadre du processus de création/déploiement
27
Lazy Badger

Je mets des secrets dans des fichiers cryptés que je valide ensuite. La phrase de passe est fournie lors du lancement du système, ou elle est stockée dans un petit fichier que je ne valide pas. Il est agréable qu'Emacs gère joyeusement ces fichiers cryptés. Par exemple, le fichier init emacs comprend: (charger "secrets.el.gpg"), ce qui fonctionne - me demandant le mot de passe dans ces rares cas lorsque je démarre l'éditeur. Je ne m'inquiète pas que quelqu'un brise le cryptage.

14
Ben Hyde

Ceci est très spécifique à Android/Gradle mais vous pouvez définir les clés dans votre _ gradle.properties fichier situé dans user home/.gradle/. Ceci est également utile car vous pouvez utiliser différentes propriétés en fonction du buildType ou de la saveur, c'est-à-dire l'API pour le développeur et différente pour la version.

gradle.properties

MY_PRIVATE_API_KEY=12356abcefg

build.gradle

buildTypes {
        debug{
            buildConfigField("String", "GOOGLE_VERIFICATION_API_KEY", "\"" + MY_PRIVATE_API_KEY +"\"")
            minifyEnabled false
            applicationIdSuffix ".debug"
            }
        }

Dans le code que vous référencez comme ceci

String myAPI = BuildConfig.GOOGLE_VERIFICATION_API_KEY;
14
scottyab

Vous n'êtes pas censé distribuer cette clé avec votre application ou la stocker dans le référentiel de code source. Cette question demande comment faire cela, et ce n'est pas ce qui se fait normalement.

Application Web mobile

Pour Android/iPhone, l'appareil doit demander la CLÉ à votre propre service Web lors de la première exécution de l'application. La clé est ensuite stockée dans un endroit sûr. Si la clé doit être modifiée ou révoquée par l'éditeur. Votre service Web peut publier une nouvelle clé.

Application Web hébergée

Les clients utilisant une licence de votre logiciel devront saisir manuellement la clé lors de la première configuration du logiciel. Vous pouvez donner à tout le monde la même clé, des clés différentes ou les obtenir.

Code source publié

Vous stockez votre code source dans un référentiel public mais pas la clé. Dans la configuration du fichier, vous ajoutez les lignes * placez la clé ici *. Lorsqu'un développeur utilise votre code source, il fait une copie du sample.cfg fichier et ajoutez leur propre clé.

Vous ne conservez pas votreconfig.cfg fichier utilisé pour le développement ou la production dans le référentiel.

11
Reactgular

Utilisez des variables d'environnement pour les choses secrètes qui changent pour chaque serveur.

http://en.wikipedia.org/wiki/Environment_variable

Leur utilisation dépend de la langue.

5
Filipe Giusti

Je pense que c'est un problème avec lequel tout le monde a eu du mal à un moment donné.

Voici un flux de travail que j'ai utilisé, qui pourrait fonctionner pour vous. Il utilise .gitignore avec une torsion:

  1. Tous les fichiers de configuration vont dans un dossier spécial (avec des exemples de fichiers de configuration - facultatif)
  2. Tous les fichiers de configuration sont inclus dans .gitignore, afin qu'ils ne deviennent pas publics
  3. Configurer un serveur gitolite (ou votre serveur git préféré) sur une boîte privée
  4. Ajouter un dépôt avec tous les fichiers de configuration sur le serveur privé
  5. Ajoutez un script pour copier les fichiers de configuration dans le dossier spécial du référentiel principal (facultatif)

Maintenant, vous pouvez cloner le dépôt de configuration sur n'importe quel système de développement et de déploiement. Exécutez simplement le script pour copier les fichiers dans le bon dossier et vous avez terminé.

Vous obtenez toujours tous les bonbons GitHub, partagez votre code avec le monde et les données sensibles ne sont jamais dans le référentiel principal, donc elles ne sont pas rendues publiques. Ils ne sont encore qu’une extraction et une copie de tout système de déploiement.

J'utilise une boîte de 15 $/an pour le serveur git privé, mais vous pouvez également en configurer un à la maison, selon l'exigence du pas cher ;-)

PS: Vous pouvez également utiliser un sous-module git ( http://git-scm.com/docs/git-submodule ), mais j'oublie toujours les commandes, donc des règles rapides et sales!

4
Kostas

Utilisez le chiffrement, mais fournissez une clé principale au démarrage, comme mot de passe sur la console, dans un fichier que seul l'utilisateur du processus peut lire, ou à partir d'un magasin de clés fourni par le système comme le trousseau Mac OS ou le magasin de clés Windows.

Pour une livraison continue, vous aurez besoin d'enregistrer diverses clés quelque part. La configuration doit être démarquée du code, mais il est très logique de la garder sous contrôle de révision.

2
erickson

3 Stratégies, pas encore mentionnées (?)

À l'enregistrement ou dans un crochet de pré-enregistrement VCS

  • recherche de chaînes à entropie élevée, exemple- detect-secrets
  • regex recherche des modèles de clés API bien connus. Les clés AKIA * d'AWS en sont un exemple, git-secrets est un outil basé sur cela. En outre, des noms de variables comme "mot de passe" avec attribution constante.
  • rechercher des secrets connus - vous connaissez vos secrets, recherchez le texte pour eux. Ou utilisez un outil, j'ai écrit ceci preuve de concept .

Stratégies déjà mentionnées

  • stocker dans un fichier en dehors de l'arborescence source
  • l'avoir dans l'arborescence source, mais dire à VCS de l'ignorer
  • les variables d'environnement sont une variation du stockage des données en dehors de l'arborescence source
  • juste ne donnez pas les précieux secrets aux développeurs
1
MatthewMartin

Gardez les informations privées hors de votre contrôle de source. Créez une valeur par défaut non chargée pour la distribution et laissez votre VCS ignorer la vraie. Votre processus d'installation (manuel, configure/build ou assistant) doit gérer la création et le remplissage du nouveau fichier. Modifiez éventuellement les autorisations sur le fichier pour vous assurer que seul l'utilisateur requis (serveur Web?) Peut le lire.

Avantages:

  • Ne suppose pas entité de développement == entité de production
  • Ne suppose pas que tous les collaborateurs/réviseurs de code sont dignes de confiance
  • Évitez les erreurs faciles en le gardant hors du contrôle de version
  • Installations faciles à automatiser avec une configuration personnalisée pour QA/builds

Si vous le faites déjà et que vous l'archivez accidentellement, ajoutez-le au .gitignore De votre projet. Cela rendra impossible de recommencer.

Il y a beaucoup de nombreux hôtes Git gratuits qui fournissent des référentiels privés. Bien que vous ne deviez jamais mettre à jour vos informations d'identification, vous pouvez être bon marché et avoir également des dépôts privés. ^ _ ^

0
Adrian Schneider