如何处理Google App Engine中的机密?

时间:2019-10-14 07:26:23

标签: google-app-engine google-cloud-platform google-cloud-kms google-secret-manager

我的应用程序需要一堆秘密来运行:数据库凭据,API凭据等。它正在Google App Engine标准Java 11中运行。我需要这些秘密作为环境变量或应用程序参数 >,以便我的框架可以选择它们并相应地建立连接。我的特定框架是Spring Boot,但是我相信Django,Rails和许多其他框架都使用相同的方法。

做到这一点的最佳方法是什么?

我对这个问题的答案之一是use Google Cloud Key Management,它看起来很有希望,但是我不知道如何在App Engine中将这些值转换为环境变量。可能吗?我已经读过Setting Up Authentication for Server to Server Production Applications,但那里没有任何迹象表明如何将机密信息转换为App Engine中的环境变量(我想念它吗?)。

我见过的其他选择包括将它们硬编码在app.yaml或从未提交并存在于我的计算机中的文件中,这意味着我是唯一可以部署的文件...我可以甚至没有从另一台机器部署。这对我来说是个问题。

我看到的另一个潜在解决方案是将问题委托给Google Cloud Build,以便它从CKM中获取值/文件并将其推送到App Engine(12)。我不使用GCB,但我会怀疑,因为它是如此基本。

我真的希望App Engine像Heroku一样有一个环境变量页面。

5 个答案:

答案 0 :(得分:9)

[更新] (截至2020年2月) GCP的秘密管理员处于测试版,请参阅:

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

有关特定于Java的实现,请参见: https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets#secretmanager-access-secret-version-java

您的特定解决方案将取决于您应用程序的设置方式,但是您应该能够访问机密信息并使用值创建环境变量,或者将其传递给您的应用程序。

您可以使用GCP IAM创建服务帐户来管理访问或向现有成员/服务添加类似Secret Manager Secret Accessor之类的角色(例如,在这种情况下,我将该权限添加到了App Engine default service account )。

我使用GAE标准的Node.js进行了尝试,它似乎运行良好;我没有进行任何性能测试,但是应该没问题,特别是如果您主要需要在应用启动时或在构建过程中需要这些秘密。

对于本地(非GCP)开发/测试,您可以创建具有相应秘密管理员权限的服务帐户,并获取json服务密钥。然后,您将名为GOOGLE_APPLICATION_CREDENTIALS的环境变量设置为文件的路径,例如:

export GOOGLE_APPLICATION_CREDENTIALS=/path/to/local_service_key.json

,并且在该Shell会话中运行的应用应获得许可,而无需任何其他身份验证代码。 参见:https://cloud.google.com/docs/authentication/getting-started (您可能要从版本控制中排除密钥文件。)

答案 1 :(得分:2)

到目前为止,App Engine Standard Standard还没有Google提供的用于存储应用程序机密的解决方案。

[更新]

我注意到您对另一个答案的评论,即您要求环境变量在拥有应用程序控制之前必须有效。在这种情况下,您今天无法使用App Engine。我将部署到更适合您的系统目标的其他服务(Kubernetes),该服务可以提供托管机密。

[END UPDATE]

对于App Engine Standard的机密,您有两种选择:

  1. 将机密作为环境变量存储在app.yaml中
  2. 将机密存储在其他位置。

对于这两个选项,您都可以通过加密来增加安全性。但是,添加加密会添加另一个您必须以某种方式提供给应用程序的秘密(解密密钥)。鸡或蛋的情况。

App Engine Standard使用服务帐户。该服务帐户可以用作身份来控制对其他资源的访问。其他资源的示例是KMS和Cloud Storage。这意味着您可以安全地访问KMS或云存储,而无需在App Engine中添加其他秘密。

让我们假设您的公司希望对所有应用程序机密进行加密。我们可以将App Engine服务帐户用作授权访问单个密钥的KMS的身份。

注意:以下示例使用Windows语法。对于Linux / macOS,将行继续^替换为\

创建KMS密钥环。密钥环无法删除,因此这是一次性操作。

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

gcloud kms keyrings create %GCP_KMS_KEYRING% --location global

创建KMS密钥。

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

将服务帐户添加到我们创建的密钥环和密钥的KMS策略中。

这将允许App Engine解密数据,而无需KMS的机密。服务帐户标识提供访问控制。 KMS不需要任何角色。您需要提供可包含在app.yaml中的KMS密钥环和密钥名。

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%

对于此示例,我们假设您需要访问MySQL数据库。我们将凭证存储在JSON文件中并对其进行加密。该文件名为config.json

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

使用Cloud KMS加密config.json并将加密结果存储在config.enc中:

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

加密的文件可以存储在Cloud Storage中。由于已加密,因此可以将文件与构建文件一起存储,但是我不建议这样做。

最后一步是用Java编写代码,这是使用KMS来使用KMS解密文件config.enc的程序的一部分。 Google提供了许多KMS解密示例:

Java KMS Decrypt

Java Samples

答案 2 :(得分:1)

对于秘密管理,我个人是Berglas项目的粉丝。它基于KMS,此外还管理DEK和KEK

今天用Go语言编写,并且与Java不兼容。 I wrote a python library给一些同事。如果您打算使用Java包,我可以编写它。这不是很难。

让我知道

答案 3 :(得分:0)

Berglas看起来很有趣。

另一种选择是将机密信息放入app.yaml文件(可以有多个文件)中,并在将其提交到版本控制之前对其进行加密。

有许多工具可以在将机密放入版本控制之前对其进行加密,例如https://github.com/StackExchange/blackbox

优点:

  • 用途广泛
  • 与其他选项相比,我发现它更易于理解
  • 易于上手

缺点:

  • 您无法真正删除某个人的访问权限(因为可以始终复制该文件),因此有时会有旋转秘密
  • 很难将未加密的文件保存在存储库之外。您习惯了它,并忽略了文件和/或脚本,通常没关系。

答案 4 :(得分:-1)

这些选项或多或少是您提到的。一般来说,Google Cloud Key Management是一种处理凭证和机密信息的好方法。它具有一个带有methods 的REST API,必须使用该API才能实现您的目标。例如,您具有用于获取加密密钥,keyRings,cryptoKeysVersions等的“ get”方法。

例如,这里有一个guide关于如何为您的应用设置身份验证。这里在github上也有一个不错的代码示例。

如果您认为需要额外的安全性,也可以使用secret rotation technique

也可以选择对app.yaml中的值进行硬编码,尽管不建议将其作为最佳实践。 app.yaml 不会仅存在于您的计算机上。它还将被部署,您甚至可以从App引擎的GCP控制台的“版本”->“配置”面板中看到它。因此,您无需担心。