当前位置: 首页 > 知识库问答 >
问题:

如何处理谷歌应用引擎中的秘密?

翁翰
2023-03-14

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

最好的方法是什么?

我对这个问题的一个答案是使用谷歌云密钥管理,这看起来很有希望,但我不知道如何将这些值转化为应用引擎中的环境变量。有可能吗?我已经读过为服务器到服务器的生产应用程序设置身份验证,但我没有看到任何关于如何将秘密转化为应用程序引擎中的环境变量的指示(我错过了吗?)。

我见过的其他替代方法包括将它们硬编码到< code>app.yaml或另一个文件中,该文件永远不会被提交并保存在我的机器中,这意味着我是唯一可以部署的人...我甚至不能从另一台机器部署。这对我来说是个问题。

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

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

共有3个答案

薛修能
2023-03-14

您可以在构建时将秘密作为env变量传递。此示例检索一个条带API键,并在云构建中更新app.yaml,确保本地文件不会意外签入源代码控制

首先,确保CloudBuild服务帐户具有IAM角色<code>Secret Manager Secret Accessor

runtime: python39
env: standard

instance_class: F4

automatic_scaling:
  max_instances: 1

env_variables:
  STRIPE_API_KEY: STRIPE_API_VAR

etc
etc
steps:
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
  entrypoint: 'bash'
  args:
      - -c
      - |
        echo 'my api key from secret manager is '$$STRIPE_API_VAR
        sed -i "s|STRIPE_API_VAR|$$STRIPE_API_VAR|g" app.dev.yaml
        cat app.dev.yaml # you can now see the secret value inserted as the env variable
        gcloud app deploy --appyaml=app.dev.yaml # deploy with the updated app.yaml, the local copy of the file is not changed
  secretEnv: ['STRIPE_API_VAR']

availableSecrets:
  secretManager:
  - versionName: projects/$PROJECT_ID/secrets/stripe-api-key/versions/latest
    env: 'STRIPE_API_VAR'
韦寒
2023-03-14

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

[更新]

我注意到你对另一个答案的评论,即在拥有应用程序控制之前,您需要环境变量有效。在这种情况下,您今天没有App Engine的选项。我会部署到更适合您的系统目标的不同服务(Kubernetes),可以提供托管密钥。

[结束更新]

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

  1. 将机密作为环境变量存储在 app.yaml 中
  2. 将秘密存放在其他地方。

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

App Engine Standard使用服务帐户。此服务号可用作身份来控制对其他资源的访问。其他资源的示例是KMS和Cloud Storage。这意味着您可以安全地访问KMS或Cloud Storage,而无需向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 不需要任何角色。您需要提供 KMS 密钥环和密钥名称,它们可以包含在 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%

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

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

使用云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解密文件的程序的一部分config.enc使用KMS。谷歌有许多KMS解密的例子:

Java KMS解密

Java 示例

尹兴生
2023-03-14

[更新](截至2020年2月)GCP的秘密经理处于测试阶段,请参见:

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

有关特定于Java的实现,请参阅:https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets#secretmanager-访问java的秘密版本

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

您可以使用GCP IAM创建服务帐户来管理访问权限,或者将类似< code > Secret Manager Secret Accessor 的角色添加到现有成员/服务中(例如,在本例中,我将该权限添加到了< code>App Engine默认服务帐户)。

我在GAE标准上尝试了Node.js,它似乎工作得很好;我没有做任何性能测试,但应该没问题,特别是如果你主要需要应用程序启动或作为构建过程的一部分的机密。

对于本地(非GCP)开发/测试,您可以创建一个具有适当的secret manager权限的服务帐户,并获得json服务密钥。然后,将名为< code > GOOGLE _ APPLICATION _ CREDENTIALS 的环境变量设置为文件的路径,例如:

export GOOGLE_APPLICATION_CREDENTIALS=/path/to/local_service_key.json

并且在该shell会话中运行的应用程序应该获得权限,而不需要任何额外的授权代码。请参阅:https://cloud . Google . com/docs/authentic ation/getting-started(您可能希望将密钥文件排除在版本控制之外。)

 类似资料:
  • 在GAE中,我只使用默认域名:https://*。appspot。com,所以我不需要生成自签名证书。 谷歌应用程序引擎文档指定应用程序的运行方式。yaml应配置为服务于SSL连接: https://cloud.google.com/appengine/docs/standard/go/config/appref#handlers_secure 但为了在Go中提供HTTPS连接,我编写了以下代码示

  • 我有一个应用引擎项目。 我也有谷歌云功能。 我想从App Engine项目中调用谷歌云功能。我就是没法让它发挥作用。 是的,如果我将函数完全公开(即将云函数设置为“允许所有流量”,并为“所有用户”创建一个允许调用函数的规则),它就可以工作。但是如果我限制这两个设置中的任何一个,它会立即停止工作,我得到403。 应用程序和函数在同一个项目中,所以我至少假设将函数设置为“仅允许内部流量”应该可以正常工

  • 具体到基于Docker的部署,这两者之间有什么区别?由于Google App Engine Flexible现在也支持基于Dockerfile的部署,而且它也是完全管理的服务,所以它似乎比在Container Engine上配置Kubernetes部署更可取,不是吗? 有哪些用例更倾向于使用Google容器引擎而不是灵活的应用引擎?

  • 谷歌云的功能似乎非常有趣,因为它是无服务器和零维护的解决方案。但是,什么时候在谷歌应用程序引擎上使用谷歌云功能合适呢?

  • 我正在app engine上构建一个web应用程序。在我的例子中,这是建立在django Nonl的基础上的,但关键是它使用的是谷歌的数据存储。 我喜欢这样一个事实,即我不需要处理复制、分片、备份等,但有一件事总是妨碍我,那就是最终的一致性,这似乎妨碍了实现一个通用的Web应用程序模式,我称之为“添加 假设我有一个项目管理应用程序。项目是它的中心模型。现在有一个网页页面,我可以在其中看到所有项目的

  • 是否有人有链接或可以提供Java谷歌应用程序引擎项目的代码,该项目只是与谷歌日历交互。假设从日历中获取活动。 Google Sample calendar-app engine-Sample在从HG检出后无法编译,我曾尝试搜索教程并创建自己的教程,只是运气好而已。 我已经设置了一个 API 访问项目来获取客户端机密.json。