使用 CMEK 和 Cloud Storage 限制 Cloud KMS 密钥的 encrypt/decrypt 权限

Restricting encrypt/decrypt permissions for a Cloud KMS key with CMEK and Cloud Storage

我在一个 Google 云项目中有两个存储桶,比如说 storage-project。一个使用默认加密的存储桶,另一个使用在另一个名为 security-project 的项目中创建的客户管理密钥 (CMEK) 加密的存储桶。我已将 Cloud KMS CryptoKey Encrypter/Decrypter 角色授予 storage-project 中的云存储服务帐户 (service-xxxxxxxx@gs-project-accounts.iam.gserviceaccount.com)。我可以使用拥有这两个项目的 Google 帐户成功将文件上传到此存储桶。这是预期的行为。

现在我有另一个用户帐户,在 storage-project 上具有角色 ViewerStorage Object Creator,并且 没有权限security-project。我担心的是,即使未授予用户对上述密钥的 encrypt/decrypt 权限,上述用户也能够从第二个存储桶上传和下载文件。

根据 link https://cloud.google.com/storage/docs/encryption/customer-managed-keys#service-accounts使用服务帐户 使用客户管理的加密密钥进行加密和解密。这隐含地意味着在 storage-project 上具有 Storage Object Creator 角色的任何人都可以使用该密钥 encrypt/decrypt。

有什么方法可以限制用户的 encrypt/decrypt 权限吗?更具体地说,该用户应该能够将文件上传到第一个存储桶,而不是第二个存储桶,就像我们可以使用 AWS KMS + S3 那样。

对于您可以为其设置精细 Cloud IAM 权限的每个 Cloud KMS 对象类型,该对象都有一个 testIamPermissions 方法。 testIamPermissions 方法 returns 调用者已授予该对象的权限集。 您可以使用 Documentation

限制用户的 encrypt/decrypt 权限

背景

一些背景语境对于理解这一点很重要。在 Google Cloud 上,许多服务通过 Cloud Console、API 甚至 curl(如下所示)作为 Service Account. For example, Google Cloud Storage has a unique service account per Google Cloud project. You can get the Cloud Storage service account 运行:

$ curl https://storage.googleapis.com/storage/v1/projects/${PROJECT_ID}/serviceAccount \
    --header "Authorization: Bearer $(gcloud auth print-access-token)" 

服务帐号通常表示为电子邮件,如:

service-1234567890@gs-project-accounts.iam.gserviceaccount.com

当云存储服务与其他 Google 云服务交互时,它使用此服务帐户来授权这些操作。

客户管理的加密密钥

默认情况下,所有数据在 Google 云上都是静态加密的。通常此数据使用 Google 管理的密钥加密。当您启用 Customer Managed Encryption Keys (CMEK) for Cloud Storage, you configure a Cloud Storage bucket to automatically encrypt/decrypt data that is uploaded/downloaded using a provided Cloud KMS 键时。作为客户,您可以通过 Cloud KMS 控制该密钥。

Note: I'm going to explain how this works for uploading files, but the same principles apply in reverse for downloading them.

没有 CMEK

开发人员在没有 CMEK 的情况下将对象上传到 Cloud Storage。 Cloud Storage 使用 Google 管理的加密密钥加密对象并将加密的对象保存到磁盘:

+-----------+         +---------------+                           +-------+
| Developer |         | Cloud Storage |                           | Disk  |
+-----------+         +---------------+                           +-------+
      |                       |                                       |
      | Upload object         |                                       |
      |---------------------->|                                       |
      |                       | ----------------------------------\   |
      |                       |-| Encrypt with Google-managed key |   |
      |                       | |---------------------------------|   |
      |                       |                                       |
      |                       | Write encrypted object                |
      |                       |-------------------------------------->|
      |                       |                                       |

使用 CMEK

使用 CMEK,开发人员可以将对象上传到 Cloud Storage。 Cloud Storage 使用 Cloud Storage 服务帐户调用 Cloud KMS API 来加密对象并将加密的对象保存到磁盘:

+-----------+         +---------------+                     +-----------+ +-------+
| Developer |         | Cloud Storage |                     | Cloud KMS | | Disk  |
+-----------+         +---------------+                     +-----------+ +-------+
      |                       |                                   |           |
      | Upload object         |                                   |           |
      |---------------------->|                                   |           |
      |                       |                                   |           |
      |                       | Encrypt this object               |           |
      |                       |---------------------------------->|           |
      |                       |                                   |           |
      |                       |       Here's the encrypted object |           |
      |                       |<----------------------------------|           |
      |                       |                                   |           |
      |                       | Write encrypted object            |           |
      |                       |---------------------------------------------->|
      |                       |                                   |           |

这里最重要的一点是 Cloud KMS API 是使用 Cloud Storage 服务帐户的身份调用的,而不是 调用开发者的身份。

这是设计使然,因为大多数客户希望 CMEK 对开发人员透明。当您在 Cloud Storage 存储桶上启用 CMEK 时,开发人员无需了解 CMEK 配置。他们正常使用云存储 API,而云存储使用您指定的密钥负责 encryption/decryption 操作。开发人员不需要 Cloud KMS 密钥的权限,因为如上图所示,开发人员从不直接与 Cloud KMS 交互。

限制访问

因此,重新审视您最初的问题:

Is there any way that I could restrict encrypt/decrypt permission for a user? More specifically, this user should be able to upload files to the first storage bucket, and not to the second bucket, like we could do with AWS KMS + S3.

这里有几个选项:

  1. 您可以使用应用层加密 (ALE) 而不是 CMEK。您仍然可以使用 Cloud KMS,但开发人员使用 Cloud KMS 加密数据保存到 Cloud Storage 之前:

    +-----------+                       +-----------+ +---------------+                                      +-------+
    | Developer |                       | Cloud KMS | | Cloud Storage |                                      | Disk  |
    +-----------+                       +-----------+ +---------------+                                      +-------+
          |                                   |               |                                                  |
          | Encrypt this object               |               |                                                  |
          |---------------------------------->|               |                                                  |
          |                                   |               |                                                  |
          |       Here's the encrypted object |               |                                                  |
          |<----------------------------------|               |                                                  |
          |                                   |               |                                                  |
          | Upload KMS-encrypted object       |               |                                                  |
          |-------------------------------------------------->|                                                  |
          |                                   |               | ----------------------------------\              |
          |                                   |               |-| Encrypt with Google-managed key |              |
          |                                   |               | |---------------------------------|              |
          |                                   |               |                                                  |
          |                                   |               | Write KMS-encrypted, Google-encrypted object     |
          |                                   |               |------------------------------------------------->|
          |                                   |               |                                                  |
    
  2. 不授予用户对存储桶的权限。您需要限制存储桶的 IAM 权限,而不是限制 密钥 的 IAM 权限。