3

I am using cloud storage upload a file with kms key. Here is my code:

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'
});

I have a cloud-storage-admin.json service account with cloud storage admin permission. Initialize the storage with this service account.

const storage: Storage = new Storage({
  projectId: process.env.PROJECT_ID,
  keyFilename: path.resolve(__dirname, '../.gcp/cloud-storage-admin.json')
});

And, I use gcloud kms keys add-iam-policy-binding add roles/cloudkms.cryptoKeyEncrypterDecrypter to cloud-storage-admin.json service account.

When I try to upload a file with kms key, still got this permission error:

Permission denied on Cloud KMS key. Please ensure that your Cloud Storage service account has been authorized to use this key.

update

☁  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
Lin Du
  • 88,126
  • 95
  • 281
  • 483

2 Answers2

8

When you use kmsKeyName, Google Cloud Storage is the entity calling KMS, not your service account. It's a bit confusing:

  1. Your service account has permission to call the Cloud Storage API
  2. The Cloud Storage service account then calls the KMS API in transit

You will need to get the Cloud Storage service account and grant that service account the ability to invoke Cloud KMS:

  • Option 1: Open the API explorer, authorize, and execute
  • Option 2: Install gcloud, authenticate to gcloud, install oauth2l, and run this curl command replacing [PROJECT_ID] with your project ID:

    curl -X GET -H "$(oauth2l header cloud-platform)" \
      "https://www.googleapis.com/storage/v1/projects/[PROJECT_ID]/serviceAccount"
    
  • Option 3: Trust me that it's in the format service-[PROJECT_NUMBER]@gs-project-accounts.iam.gserviceaccount.com and get your [PROJECT_NUMBER] from gcloud projects list or the web interface.
sethvargo
  • 26,739
  • 10
  • 86
  • 156
  • Sorry, still don't know where is wrong. I am using gcloud sdk and @google_cloud/storage nodejs client library. Update the question, as you can see, I already grant the `roles/cloudkms.cryptoKeyEncrypterDecrypter` to my cloud storage service account : `cloud-storage-admin@.iam.gserviceaccount.com` – Lin Du May 28 '19 at 11:02
  • `cloud-storage-admin@.iam.gserviceaccount.com` isn't the correct service account. That appears to be a service account in your project. The Cloud Storage service account lives outside your project in `gcs-project.accounts.iam.gserviceaccount.com`. You need to grant the KMS permission to that service account. – sethvargo May 28 '19 at 19:03
  • Do you mean I should grant `cloud-storage-admin@.iam.gserviceaccount.com` service account `cloud KMS admin` permission in GCP - IAM? – Lin Du May 29 '19 at 02:31
  • 1
    No, you should grant `service-[PROJECT_NUMBER]@gs-project-accounts.iam.gserviceaccount.com` the IAM role `roles/cloudkms.cryptoKeyEncrypterDecrypter`. You can get your project number from `gcloud projects list`. – sethvargo May 29 '19 at 04:38
  • Doesn't this mean that anyone who can log into the Cloud Storage browser Web UI then has the ability to encrypt/decrypt with that key? I was hoping to lock the key down to a single service account (the one I created). – Neil C. Obremski Jun 18 '19 at 22:34
  • do you mind looking at this please https://stackoverflow.com/questions/69710603/cloud-kms-error-when-attempting-to-use-boot-disk-encryption-key – floormind Oct 25 '21 at 17:01
0

Is it possible to encrypt file using provided service account instead of cloud storage service account? It's a bit confusing. If I login to Cloud Storage then I can see all files decrypted (because Cloud storage service account has permission to decrypt it). If I use my service account then any person who log in to Cloud storage will see encrypted files (of course this person should not have access to KMS key).

I tried to encrypt this file on application side (using KMS) but there is a length limitation (65KB).

Herr Mefisto
  • 567
  • 1
  • 4
  • 5