使用云存储时对 Cloud KMS 密钥的权限被拒绝
Permission denied on Cloud KMS key when using cloud storage
我正在使用 cloud storage
使用 kms 密钥上传文件。这是我的代码:
await storage.bucket(config.bucket).upload(file, {
kmsKeyName: `projects/${process.env.PROJECT_ID}/locations/global/keyRings/test/cryptoKeys/nodejs-gcp`,
destination: 'mmczblsq.kms.encrypted.doc'
});
我有一个具有 cloud storage admin
权限的 cloud-storage-admin.json
服务帐户。使用此服务帐户初始化 storage
。
const storage: Storage = new Storage({
projectId: process.env.PROJECT_ID,
keyFilename: path.resolve(__dirname, '../.gcp/cloud-storage-admin.json')
});
而且,我使用 gcloud kms keys add-iam-policy-binding
添加 roles/cloudkms.cryptoKeyEncrypterDecrypter
到 cloud-storage-admin.json
服务帐户。
当我尝试使用 kms 密钥上传文件时,仍然出现此权限错误:
Permission denied on Cloud KMS key. Please ensure that your Cloud Storage service account has been authorized to use this key.
更新
☁ nodejs-gcp [master] ⚡ gcloud kms keys get-iam-policy nodejs-gcp --keyring=test --location=global
bindings:
- members:
- serviceAccount:cloud-storage-admin@<PROJECT_ID>.iam.gserviceaccount.com
- serviceAccount:service-16536262744@gs-project-accounts.iam.gserviceaccount.com
role: roles/cloudkms.cryptoKeyEncrypterDecrypter
etag: BwWJ2Pdc5YM=
version: 1
当您使用 kmsKeyName
时,Google 云存储是调用 KMS 的实体,而不是您的服务帐户。有点混乱:
- 您的服务帐号有权调用云存储API
- 云存储服务帐户然后在传输中调用 KMS API
您需要 get the Cloud Storage service account 并授予该服务帐户调用 Cloud KMS 的能力:
- 选项 1:Open the API explorer、授权并执行
选项 2:安装 gcloud, authenticate to gcloud, install oauth2l 和 运行 此 curl
命令将 [PROJECT_ID]
替换为您的项目 ID:
curl -X GET -H "$(oauth2l header cloud-platform)" \
"https://www.googleapis.com/storage/v1/projects/[PROJECT_ID]/serviceAccount"
- 选项 3:相信我,它的格式是
service-[PROJECT_NUMBER]@gs-project-accounts.iam.gserviceaccount.com
,然后从 gcloud projects list
或 Web 界面获取您的 [PROJECT_NUMBER]
。
是否可以使用提供的服务帐户而不是云存储服务帐户来加密文件?这有点令人困惑。如果我登录到云存储,那么我可以看到所有已解密的文件(因为云存储服务帐户具有解密它的权限)。如果我使用我的服务帐户,那么任何登录云存储的人都会看到加密文件(当然这个人不应该访问 KMS 密钥)。
我尝试在应用程序端(使用 KMS)加密此文件,但存在长度限制 (65KB)。
我正在使用 cloud storage
使用 kms 密钥上传文件。这是我的代码:
await storage.bucket(config.bucket).upload(file, {
kmsKeyName: `projects/${process.env.PROJECT_ID}/locations/global/keyRings/test/cryptoKeys/nodejs-gcp`,
destination: 'mmczblsq.kms.encrypted.doc'
});
我有一个具有 cloud storage admin
权限的 cloud-storage-admin.json
服务帐户。使用此服务帐户初始化 storage
。
const storage: Storage = new Storage({
projectId: process.env.PROJECT_ID,
keyFilename: path.resolve(__dirname, '../.gcp/cloud-storage-admin.json')
});
而且,我使用 gcloud kms keys add-iam-policy-binding
添加 roles/cloudkms.cryptoKeyEncrypterDecrypter
到 cloud-storage-admin.json
服务帐户。
当我尝试使用 kms 密钥上传文件时,仍然出现此权限错误:
Permission denied on Cloud KMS key. Please ensure that your Cloud Storage service account has been authorized to use this key.
更新
☁ nodejs-gcp [master] ⚡ gcloud kms keys get-iam-policy nodejs-gcp --keyring=test --location=global
bindings:
- members:
- serviceAccount:cloud-storage-admin@<PROJECT_ID>.iam.gserviceaccount.com
- serviceAccount:service-16536262744@gs-project-accounts.iam.gserviceaccount.com
role: roles/cloudkms.cryptoKeyEncrypterDecrypter
etag: BwWJ2Pdc5YM=
version: 1
当您使用 kmsKeyName
时,Google 云存储是调用 KMS 的实体,而不是您的服务帐户。有点混乱:
- 您的服务帐号有权调用云存储API
- 云存储服务帐户然后在传输中调用 KMS API
您需要 get the Cloud Storage service account 并授予该服务帐户调用 Cloud KMS 的能力:
- 选项 1:Open the API explorer、授权并执行
选项 2:安装 gcloud, authenticate to gcloud, install oauth2l 和 运行 此
curl
命令将[PROJECT_ID]
替换为您的项目 ID:curl -X GET -H "$(oauth2l header cloud-platform)" \ "https://www.googleapis.com/storage/v1/projects/[PROJECT_ID]/serviceAccount"
- 选项 3:相信我,它的格式是
service-[PROJECT_NUMBER]@gs-project-accounts.iam.gserviceaccount.com
,然后从gcloud projects list
或 Web 界面获取您的[PROJECT_NUMBER]
。
是否可以使用提供的服务帐户而不是云存储服务帐户来加密文件?这有点令人困惑。如果我登录到云存储,那么我可以看到所有已解密的文件(因为云存储服务帐户具有解密它的权限)。如果我使用我的服务帐户,那么任何登录云存储的人都会看到加密文件(当然这个人不应该访问 KMS 密钥)。
我尝试在应用程序端(使用 KMS)加密此文件,但存在长度限制 (65KB)。