【问题标题】:Best way to secure an internal API on Google Cloud Run using Google Cloud Endpoints使用 Google Cloud Endpoints 在 Google Cloud Run 上保护内部 API 的最佳方式
【发布时间】:2020-12-24 12:45:59
【问题描述】:

场景

我在 Cloud Run(grpc,但问题也适用于 http)中托管我希望保护的 API。目标是提供对我们组织中多个应用程序的访问。请注意,每个应用程序都有多个在另一个位置运行的实例(每个外部客户端一个)。该 API 仅供内部使用,不会被网络浏览器直接访问。

选项

我已经确定了以下选项:

  1. 不使用 Cloud Endpoints:我可以让我的 API 不公开并由服务帐户保护。 Bearer 令牌(id 令牌)可以在应用程序中自动生成。
  2. Cloud Endpoints + API 密钥:对于每个应用程序,我都会生成一个 API 密钥,供该应用程序的所有实例使用。这很容易设置,因为它只需要发送一个额外的标头。
  3. Cloud Endpoints + 自签名 jwt:我使用服务帐户生成自签名令牌(请参阅 GCP documentation on Service-to-Service communication)并使用该服务帐户配置端点。多个应用程序要么获得自己的服务帐户,要么我从同一个帐户生成新密钥。请注意,并非所有库都提供自签名令牌,并且需要一些手动工作。因此刷新令牌也是手动的。
  4. Cloud Endpoints + Google ID:仅提供身份验证,不提供授权。这也意味着拥有 Google 帐户的每个人都可以访问我的 API (!)。优点是生成 ID 令牌的工具很简单。
  5. Cloud Endpoints + API Key + Google ID
  6. Cloud Endpoints + API Key + 自签名 jwt

问题

  1. 哪个选项最适合我的方案? (欢迎提出其他选择/建议)
  2. 选项 1 通常被认为是安全的吗?如果是这样,为什么还要使用 Cloud Endpoints?
  3. Google 文档提到了不同形式的身份验证(请参阅GCP documentation on Authentication methods)。但是,感觉其中一些是授权(例如 API 密钥和服务帐户),而其中一些是身份验证(例如 Google ID)。这是一个正确的评估吗?
  4. 我假设 GCP 了解 3 处理服务帐户,并且可以以自己的方式验证它们;没有服务帐户密钥的人无法获得访问权限。
  5. 在选项 3 中:我认为使用多个服务帐户更好,每个应用程序一个,最好每个实例一个密钥。这会被认为是选项 3 的最佳方式吗?
  6. 是否值得在实际 API 中执行额外的验证?如果是这样,我为什么还要使用 Cloud Endpoints?
  7. GCP 文档没有提到选项 4 的大问题。我认为这应该更清楚。
  8. 使用选项 5 有什么好处?我可以识别谁拨打电话的事实?那为什么不制作更多的 API 密钥呢?
  9. 选项 6 有用吗?虽然这在 Cloud Endpoints 中被视为身份验证,但这实际上是授权,对吗?
  10. 如果 API被网络浏览器访问会发生什么变化?

【问题讨论】:

    标签: authentication google-cloud-platform google-cloud-endpoints google-cloud-run


    【解决方案1】:

    这是我的意见(但您的问题是基于意见的,可能会被关闭)

    1. 这取决于!主要是您的客户端应用程序功能!如果您能够基于服务帐户生成 Google 签名的 JWT,那就完美了(不是 Cloud Endpoint,产品的本机安全性)。 请记住,添加一个额外的层意味着一个新的可能故障点,一个需要维护和更新的新东西。如果能避免就更好了!

    2. 是的,请参阅我之前的问题。如果您的客户端应用无法生成动态凭证,您可以使用静态凭证,如 API Key(解决静态凭证的所有问题,如轮换、窃取、过期......)

    3. Google 执行身份验证是所有情况。仅针对 GCP 产品,它基于 IAM 角色和权限进行授权。

    4. 对于#3,签名的公钥必须是已知的。使用服务帐户,Google 知道公钥。您可以配置自定义身份验证,并且可以提供自己的公钥(例如,如果您使用自管理的 OIDC 服务器,则为您的 PKI)

    5. 每个应用程序 1 个服务帐户(如果很棒):每个应用程序可以拥有不同的权限。如果一个应用程序遭到破坏(并且服务帐户被盗),服务帐户不会被过度授予,您不必更改其他应用程序上的服务帐户密钥。但是,每个项目最多只能有 100 个服务帐户。我没有抓住“每个实例的密钥”。如果您需要旋转它们或将其中的一个保存在保险箱中(在您身边),您可以生成多个密钥。如果您有其他想法,请发表评论!

    6. 这取决于!您的客户端应用程序是否具有不同的授权?如果是这样,您必须识别调用者的身份,然后在您的服务内部匹配其授权(我们通常使用 Firestore 执行此操作)。如果简单的身份验证就足够了,请不要执行额外的检查。为什么选择云端点?如果您有私有模式的 Cloud Run(仅接受 Google 签名的 JWT),并且您的客户端应用只能使用 API KEY,则您需要一个中介来对客户端 APP 进行身份验证并在转发请求时生成 JWT

    7. 如前所述,Google 仅执行身份验证。对于您自己的应用程序,您必须自己管理授权。是的,如果您接受第 3 方 OIDC 提供商(Google、Facebook、LinkedIn,就像您可以使用 Firebase Auth(或 Cloud Identity Platform)一样,您可以打开您的 API 以进行所有有效的身份验证)

    8. 在这种情况下,Google ID 用于(调用方的)身份验证,API KEY 用于(项目的)身份验证。首先,API 密钥标识 GCP 项目,而不是帐户(用户或服务)或应用程序。只是一个项目! (这意味着如果您想严格识别不同的应用程序(因为每个应用程序具有不同的授权),您需要每个应用程序一个 GCP 项目,每个项目一个 API 密钥,并且您无法自动生成 API 密钥,因此您需要手动执行此操作,...无聊的时刻...)。其次,在这种情况下,您可以将 API Keys 用于配额和速率限制功能(实际上,您需要 API Key 而不是 Google ID,它仅适用于 API Key)

    9. 和以前一样

    10. 如果您指的是具有经过身份验证的用户的浏览器,请使用 Firebase Auth(或 Cloud Identity Platform)对您的用户进行身份验证,仅此而已。

    这是很多信息,可能不清楚或顺序错误。如果你愿意,我写了 2 篇文章,authentication with API Keys,第二篇为 the Quotas/rate limit

    我只有谈论这个话题的法语视频。但是我会present it in english to the Serverless Day Zurich later in September,我会尝试更清楚地解释 API Keys 的这个概念以及何时使用它们!

    【讨论】:

    • 非常感谢您的精心回复!!看了你之前的帖子,好东西!这确实取决于很多。我发现文档有限,因此我对 SO 的问题 :)
    • 5.每个实例的密钥:假设您为每个客户端部署了相同的应用程序,您可以为每个客户端的相同服务帐户生成一个密钥。将身份验证(云运行)添加到端点本身是否有用/可能?最后,端点似乎是多余的,因为我可以使用服务帐户机制连接到我的内部 API。看来我的服务帐户可以生成一个允许 GCP 检查 SA 是否具有调用者权限的密钥。所以除非有调用者权限,否则没有人可以访问 api,对吗?
    • 为每个客户端生成一个密钥有 3 个问题:首先,每个服务帐户限制为 10 个密钥。其次,你的钥匙上没有名字,你也不知道钥匙属于谁。第三,密钥号码没有出现在日志中(但服务帐户电子邮件是)。万一出现问题,如果您想知道哪个客户给您打电话,拥有一个服务帐户会更清晰、更简单。
    • 如果您的客户可以使用Service Account,最好使用这种机制,避免使用Cloud Endpoint。
    猜你喜欢
    • 1970-01-01
    • 2019-10-27
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-07
    • 1970-01-01
    相关资源
    最近更新 更多