Google cloud storage 使用CMEK和云存储限制云KMS密钥的加密/解密权限
我在一个谷歌云项目中有两个存储桶,比如说存储项目。一个bucket使用默认加密,另一个bucket使用在另一个名为security project的项目中创建的客户管理密钥CMEK进行加密。我已将Cloud KMS CryptoKey Encrypter/Decrypter角色授予云存储服务帐户服务-xxxxxxxx@gs-存储项目中的project-accounts.iam.gserviceaccount.com。我可以成功地上传文件到这个存储桶使用谷歌帐户谁是所有者的两个项目。这是意料之中的行为 现在,我有了另一个用户帐户,该帐户在存储项目上具有角色查看器和存储对象创建者,但对安全项目没有权限。我担心的是,上述用户能够从第二个存储桶上载和下载文件,即使用户没有被授予上述密钥的加密/解密权限 根据链接,使用客户管理的加密密钥进行加密和解密是使用服务帐户完成的。这意味着在存储项目中具有存储对象创建者角色的任何人都可以使用该密钥进行加密/解密Google cloud storage 使用CMEK和云存储限制云KMS密钥的加密/解密权限,google-cloud-storage,google-cloud-kms,Google Cloud Storage,Google Cloud Kms,我在一个谷歌云项目中有两个存储桶,比如说存储项目。一个bucket使用默认加密,另一个bucket使用在另一个名为security project的项目中创建的客户管理密钥CMEK进行加密。我已将Cloud KMS CryptoKey Encrypter/Decrypter角色授予云存储服务帐户服务-xxxxxxxx@gs-存储项目中的project-accounts.iam.gserviceaccount.com。我可以成功地上传文件到这个存储桶使用谷歌帐户谁是所有者的两个项目。这是意料之中的
有没有办法限制用户的加密/解密权限?更具体地说,该用户应该能够将文件上载到第一个存储桶,而不是第二个存储桶,就像我们使用AWS KMS+S3所做的那样。对于您可以为其设置细粒度云IAM权限的每个云KMS对象类型,该对象都有一个testIamPermissions方法。testIamPermissions方法返回调用者为该对象授予的权限集。 您可以使用此后台限制用户的加密/解密权限 一些背景背景对于理解这一点很重要。在谷歌云上,许多服务作为一个整体运行。例如,谷歌云存储在每个谷歌云项目中都有一个唯一的服务帐户。您可以通过云控制台、API甚至curl,如下所示:
$ 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云服务交互时,它使用此服务帐户来授权这些操作
客户管理的加密密钥
默认情况下,所有数据都在谷歌云上进行加密。通常,这些数据是用谷歌管理的密钥加密的。启用时,您将配置云存储桶,以自动加密/解密使用提供的密钥上载/下载的数据。作为客户,您可以通过云KMS控制该密钥
注意:我将解释上传文件是如何工作的,但同样的原则反过来适用于下载文件
没有CMEK
如果没有CMEK,开发人员会将对象上载到云存储。云存储使用Google托管的加密密钥加密对象,并将加密对象持久化到磁盘:
+-----------+ +---------------+ +-------+
| Developer | | Cloud Storage | | Disk |
+-----------+ +---------------+ +-------+
| | |
| Upload object | |
|---------------------->| |
| | ----------------------------------\ |
| |-| Encrypt with Google-managed key | |
| | |---------------------------------| |
| | |
| | Write encrypted object |
| |-------------------------------------->|
| | |
+-----------+ +---------------+ +-----------+ +-------+
| Developer | | Cloud Storage | | Cloud KMS | | Disk |
+-----------+ +---------------+ +-----------+ +-------+
| | | |
| Upload object | | |
|---------------------->| | |
| | | |
| | Encrypt this object | |
| |---------------------------------->| |
| | | |
| | Here's the encrypted object | |
| |<----------------------------------| |
| | | |
| | Write encrypted object | |
| |---------------------------------------------->|
| | | |
与CMEK
使用CMEK,开发人员将对象上传到云存储。云存储使用云存储服务帐户调用云KMS API对对象进行加密,并将加密的对象持久化到磁盘:
+-----------+ +---------------+ +-------+
| Developer | | Cloud Storage | | Disk |
+-----------+ +---------------+ +-------+
| | |
| Upload object | |
|---------------------->| |
| | ----------------------------------\ |
| |-| Encrypt with Google-managed key | |
| | |---------------------------------| |
| | |
| | Write encrypted object |
| |-------------------------------------->|
| | |
+-----------+ +---------------+ +-----------+ +-------+
| Developer | | Cloud Storage | | Cloud KMS | | Disk |
+-----------+ +---------------+ +-----------+ +-------+
| | | |
| Upload object | | |
|---------------------->| | |
| | | |
| | Encrypt this object | |
| |---------------------------------->| |
| | | |
| | Here's the encrypted object | |
| |<----------------------------------| |
| | | |
| | Write encrypted object | |
| |---------------------------------------------->|
| | | |
这里最重要的一点是,使用云存储服务帐户的身份而不是调用开发人员的身份来调用Cloud KMS API
这是出于设计,因为大多数客户希望CMEK对开发人员透明。在云存储桶上启用CMEK时,开发人员不需要知道CMEK配置。他们像往常一样使用云存储API,云存储使用您指定的密钥负责加密/解密操作。开发人员不需要云KMS密钥的权限,因为如上图所示,开发人员从不直接与云KMS交互
限制访问
那么,重新审视你最初的问题:
有没有办法限制用户的加密/解密权限?更具体地说,该用户应该能够将文件上载到第一个存储桶,而不是第二个存储桶,就像我们可以使用AWS KMS+S3那样
您在这里有几个选项:
您可以使用应用层加密ALE而不是CMEK。您仍然可以使用Cloud KMS,但开发人员在保存到云存储之前使用Cloud KMS对数据进行加密:
+-----------+ +-----------+ +---------------+ +-------+
| 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 |
| | |------------------------------------------------->|
| | | |
不要授予用户对bucket的权限。您需要限制bucket上的IAM权限,而不是限制密钥上的IAM权限
我知道我们可以向每个用户授予粒度访问权限。但在我的例子中,即使用户没有在CMEK上明确授予加密权限,用户也可以将文件上载到启用加密的bucket。预期的行为是,只有在CMEK上具有云KMS加密密钥加密/解密器权限的用户才能将文件上载到上述存储桶,而其他用户
无法。我们可以在使用CMEK加密文件时满足上述要求,例如通过gcloud shell。在CMEK上分配了Cloud KMS CryptoKey Encrypter角色的用户可以使用该CMEK加密文件。但当从用户取消分配角色时,它将获得加密命令的权限拒绝错误。然而,当涉及GCS时,是云存储服务帐户代表用户执行加密/解密操作。因此,我们无法在用户级别限制访问。我正在寻找解决这个问题的方法。谢谢你的解释。我提到的场景和解决方案在AWS中运行良好。因此,我想确保Google Cloud KMS是否可行。@sethvargo这样看起来密钥不会离开KMS,因为云存储通过将数据发送到KMS并接收加密版本来加密对象?你能提供这个流程的参考吗?这是正确的,有点。云存储生成数据加密密钥DEK,并使用该密钥加密数据。然后将DEK发送到KMS以加密DEK。这称为信封加密。KMS从未看到明文存储对象。