使用Google Cloud Endpoints在Google Cloud Run上保护内部API的最佳方法

问题描述

场景

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

选项

我确定了以下选项:

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

问题

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

解决方法

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

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

  2. 是的,请参阅我之前的问题。如果您的客户端应用程序无法生成动态凭证,则可以使用API​​密钥之类的静态凭证(具有静态凭证的所有问题,例如轮换,窃取,到期等)

  3. 在所有情况下,Google都会执行身份验证。仅针对GCP产品,它会根据IAM角色和权限执行授权。

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

  5. 每个应用程序
  6. 1个服务帐户(如果很棒):每个应用程序可以具有不同的权限。如果一个应用程序被盗用(并且服务帐户被盗),则该服务帐户不会超额使用,您不必在其他应用程序上更改服务帐户密钥。但是,每个项目最多只能有100个服务帐户。我没有抓住“每个实例的关键”。如果您需要旋转多个钥匙或将一个钥匙放在一个安全的侧面(侧面),则可以生成多个钥匙。如果您有其他想法,请发表评论!

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

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

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

  10. 与以前相同

  11. 如果您的意思是浏览器具有经过身份验证的用户,请使用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密钥的概念以及何时使用它们!