目前,App Engine Standard Standard 没有 Google 提供的用于存储应用程序机密的解决方案。
[更新]
我注意到您对另一个答案的评论,即在您拥有应用程序控制之前,您需要环境变量有效。在这种情况下,您今天对 App Engine 没有任何选择。我将部署到更适合您可以提供托管机密的系统目标的不同服务 (Kubernetes)。
[结束更新]
对于 App Engine 标准版,您有两种密钥选择:
- 将秘密作为环境变量存储在 app.yaml 中
- 将秘密存储在其他地方。
对于这两个选项,您都可以通过加密来增加一层安全性。但是,添加加密会添加另一个秘密(解密密钥),您必须以某种方式将其提供给您的应用程序。先有鸡还是先有蛋的情况。
App Engine 标准版使用服务帐号。此服务帐户可用作身份来控制对其他资源的访问。其他资源的示例包括 KMS 和 Cloud Storage。这意味着您可以安全地访问 KMS 或 Cloud Storage,而无需向 App Engine 添加其他密钥。
假设您的公司希望加密所有应用程序机密。我们可以使用 App Engine 服务帐号作为授权访问 KMS 的身份,获取单个密钥。
注意:以下示例使用 Windows 语法。将续行替换^
为\
for 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
加密后的文件可以存储在云存储中。由于它是加密的,您可以将文件与构建文件一起存储,但我不建议这样做。
最后一步是用 Java 编写代码,该代码是您的程序的一部分,该程序使用 KMS 使用 KMS 解密文件 config.enc。谷歌有很多 KMS 解密的例子:
Java KMS 解密
Java 示例