web-dev-qa-db-fra.com

Comment gérer les secrets dans Google App Engine?

Mon application a besoin d'un tas de secrets pour fonctionner: les informations d'identification de la base de données, les informations d'identification de l'API, etc. Elle s'exécute dans Google App Engine Standard Java 11. J'ai besoin de ces secrets comme variables d'environnement ou comme arguments de mon application , afin que mon framework puisse les récupérer et établir les connexions en conséquence. Mon framework particulier est Spring Boot, mais je crois que Django, Rails et bien d'autres utilisent les mêmes méthodes.

Quelle est la meilleure façon de procéder?

L'une des réponses que j'obtiens à cette question est de tiliser Google Cloud Key Management , ce qui semble prometteur, mais je ne sais pas comment transformer ces valeurs en variables d'environnement dans App Engine. C'est possible? J'ai lu Configuration de l'authentification pour les applications de production de serveur à serveur , mais je ne vois aucune indication sur la façon de transformer les secrets en variables d'environnement dans App Engine (me manque-t-il?).

Les autres alternatives que j'ai vues incluent leur codage en dur dans app.yaml ou un autre fichier qui n'est jamais validé et qui vit sur ma machine, ce qui signifie que je suis le seul à pouvoir déployer ... Je ne peux même pas déployer à partir d'une autre machine. C'est problématique pour moi.

Une autre solution potentielle que j'ai vue consiste à déléguer le problème à Google Cloud Build, afin qu'il récupère une valeur/un fichier de CKM et le pousse vers App Engine ( 1 , 2 =). Je n'utilise pas GCB et j'en doute, car c'est tellement basique.

Je souhaite vraiment qu'App Engine ait une page de variables d'environnement comme Heroku.

3
pupeno

[Mise à jour] (à partir de février 2020) GCP's Secret Manager est en bêta, voir:

https://cloud.google.com/secret-manager/docs/overview

Pour une implémentation spécifique à Java, voir: https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets#secretmanager-access-secret-version-Java

Votre solution spécifique dépendra de la configuration de votre application, mais vous devriez pouvoir accéder aux secrets et créer des variables d'environnement avec les valeurs ou les transmettre à votre application.

Vous pouvez utiliser GCP IAM pour créer un compte de service pour gérer l'accès ou ajouter un rôle comme Secret Manager Secret Accessor à un membre/service existant (par exemple, dans ce cas, j'ai ajouté cette autorisation au App Engine default service account).

Je l'ai essayé avec Node.js sur la norme GAE, et cela semble bien fonctionner; Je n'ai fait aucun test de performance, mais ça devrait aller, surtout si vous avez principalement besoin des secrets au démarrage de l'application ou dans le cadre d'un processus de construction.

Pour le développement/test local (non GCP), vous pouvez créer un compte de service avec les autorisations de gestionnaire secret appropriées et obtenir la clé de service json. Vous définissez ensuite une variable d'environnement nommée GOOGLE_APPLICATION_CREDENTIALS vers le chemin du fichier, par exemple:

export GOOGLE_APPLICATION_CREDENTIALS=/path/to/local_service_key.json

et l'application exécutée dans cette session Shell doit récupérer les autorisations sans code d'authentification supplémentaire. Voir: https://cloud.google.com/docs/authentication/getting-started (Vous voudriez exclure le fichier clé du contrôle de version.)

2
ldg

À cette date, App Engine Standard Standard n'a pas de solution fournie par Google pour stocker les secrets d'application.

[MISE À JOUR]

J'ai remarqué votre commentaire sur une autre réponse selon laquelle vous avez besoin que les variables d'environnement soient valides avant d'avoir le contrôle des applications. Dans ce cas, vous n'avez aucune option pour App Engine aujourd'hui. Je déploierais à un service différent (Kubernetes) mieux adapté à vos objectifs système qui peuvent fournir des secrets gérés.

[FIN DE MISE À JOUR]

Vous avez deux choix pour les secrets d'App Engine Standard:

  1. Stockez les secrets en tant que variables d'environnement dans app.yaml
  2. Stockez les secrets ailleurs.

Pour les deux options, vous pouvez ajouter une couche de sécurité en les chiffrant. Cependant, l'ajout d'un chiffrement ajoute un autre secret (clé de déchiffrement) que vous devez en quelque sorte fournir à votre application. La situation du poulet ou de l'oeuf.

App Engine Standard utilise un compte de service. Ce compte de service peut être utilisé comme identité pour contrôler l'accès à d'autres ressources. Des exemples d'autres ressources sont KMS et Cloud Storage. Cela signifie que vous pouvez accéder en toute sécurité à KMS ou Cloud Storage sans ajouter un autre secret à App Engine.

Supposons que votre entreprise souhaite que tous les secrets d'application soient chiffrés. Nous pouvons utiliser le compte de service App Engine comme identité autorisée à accéder à KMS pour une seule clé.

Remarque: Les exemples suivants utilisent la syntaxe Windows. Remplacer la suite de ligne ^ avec \ pour Linux/macOS.

Créez le trousseau de clés KMS. Les porte-clés ne peuvent pas être supprimés, il s'agit donc d'une opération unique.

set GCP_KMS_KEYRING=app-keyring
set GCP_KMS_KEYNAME=app-keyname

gcloud kms keyrings create %GCP_KMS_KEYRING% --location global

Créez la clé KMS.

gcloud kms keys create %GCP_KMS_KEYNAME% ^
--location global ^
--keyring %GCP_KMS_KEYRING% ^
--purpose encryption

Ajoutez le compte de service à la stratégie KMS pour le trousseau et la clé que nous avons créés.

Cela permettra à App Engine de déchiffrer les données sans nécessiter de secrets pour KMS. L'identité du compte de service fournit un contrôle d'accès. Aucun rôle n'est requis pour KMS. Vous devrez fournir le trousseau et le nom de clé KMS qui peuvent être inclus dans app.yaml.

set GCP_SA=<replace with the app engine service acccount email adddress>
set GCP_KMS_ROLE=roles/cloudkms.cryptoKeyDecrypter

gcloud kms keys add-iam-policy-binding %GCP_KMS_KEYNAME% ^
--location global ^
--keyring %GCP_KMS_KEYRING% ^
--member serviceAccount:%GCP_SA% ^
--role %GCP_KMS_ROLE%

Pour cet exemple, supposons que vous devez accéder à une base de données MySQL. Nous allons stocker les informations d'identification dans un fichier JSON et les crypter. Le fichier est nommé config.json.

{
        "DB_Host": "127.0.0.1",
        "DB_PORT": "3306",
        "DB_USER": "Roberts",
        "DB_PASS": "Keep-This-Secret"
}

Chiffrez config.json à l'aide de Cloud KMS et stockez les résultats chiffrés dans config.enc:

call gcloud kms encrypt ^
--location=global ^
--keyring %GCP_KMS_KEYRING% ^
--key=%GCP_KMS_KEYNAME% ^
--plaintext-file=config.json ^
--ciphertext-file=config.enc

Le fichier crypté peut être stocké dans Cloud Storage. Puisqu'il est crypté, vous pouvez stocker le fichier avec vos fichiers de construction, mais je ne le recommande pas.

La dernière pièce consiste à écrire le code dans Java qui fait partie de votre programme qui utilise KMS pour décrypter le fichier config.enc en utilisant KMS. Google a un certain nombre d'exemples de décryptage KMS:

Java KMS Decrypt

exemples Java

2
John Hanley

Pour la gestion secrète, je suis personnellement fan du projet Berglas . Il est basé sur KMS et gère en outre DEK et KEK

C'est aujourd'hui écrire en Go et ce n'est pas compatible avec Java. J'ai écrit un python pour certains collègues. Je peux écrire un paquet Java si vous prévoyez de l'utiliser. Ce n'est pas très dur.

Faites le moi savoir

1

Berglas a l'air intéressant.

Une autre option consiste à mettre les secrets dans le (s) fichier (s) app.yaml (vous pouvez en avoir plusieurs) et à le chiffrer avant de le valider pour le contrôle de version.

Il existe de nombreux outils pour crypter les secrets avant de les mettre en contrôle de version, comme https://github.com/StackExchange/blackbox

Avantages:

  • Très polyvalent
  • Je trouve cela simple à comprendre par rapport aux autres options
  • Facile à démarrer

Les inconvénients:

  • Vous ne pouvez pas vraiment supprimer l'accès pour une personne (car le fichier peut toujours être copié), vous avez donc parfois des secrets de rotation
  • Il peut être difficile de garder les fichiers non chiffrés hors du référentiel. Ceux que vous y habituez et que vous ignorez des fichiers et/ou des scripts, c'est généralement OK.
0
Øyvind Skaar