I am building an http endpoint with Google Cloud Functions. I have an encrypted secret stored as a file that is loaded and decrypted in the function as a way to prevent my secret from being stored in the code. Usually I dynamically load something from Google Cloud Storage but it seems like KMS is more meant for this purpose.
The code that uses KMS looks like this:
getCredentials: async function () {
const kms = require('@google-cloud/kms');
const client = new kms.KeyManagementServiceClient();
const fs = require('fs');
let ciphertext = (fs.readFileSync('secret.enc')).toString('base64')
const name = client.cryptoKeyPath(
'[project]',
'global',
'[keyring]',
'[key]'
);
Everything runs fine locally but I can't seem to get the function to work when called with the http trigger. Checking the logs I see this:
textPayload: "Error: Permission 'cloudkms.cryptoKeyVersions.useToDecrypt' denied for resource 'projects/[projectname]/locations/global/keyRings/[keyring]/cryptoKeys/[key]'.
at Http2CallStream.call.on (/srv/functions/node_modules/@grpc/grpc-js/build/src/client.js:96:45)
at Http2CallStream.emit (events.js:194:15)
at Http2CallStream.EventEmitter.emit (domain.js:459:23)
at process.nextTick (/srv/functions/node_modules/@grpc/grpc-js/build/src/call-stream.js:71:22)
at process._tickCallback (internal/process/next_tick.js:61:11)"
I have tried all sorts of IAM permissions (including owner) with on avail so it seems like I must have a deeper misunderstanding.
This is potentially related to another issue I have where I cannot get Google Cloud Build to deploy the function. It errors without help:
starting build "b2321cdb-bd4c-4828-8d38-80a86f4fe808"
FETCHSOURCE
Initialized empty Git repository in /workspace/.git/
From https://source.developers.google.com/p/[projectname]/r/[repo]
* branch 314691d6e63199caf867c74bcd0090bc70386a0e -> FETCH_HEAD
HEAD is now at 314691d Merge pull request #2 from [repo]/tristans/update-deploy-cloudbuild
BUILD
Already have image (with digest): gcr.io/cloud-builders/gcloud
Deploying function (may take a while - up to 2 minutes)...
...............failed.
ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: Build error details not available
ERROR
ERROR: build step 0 "gcr.io/cloud-builders/gcloud" failed: exit status 1
It doesn't seem like you would need any KMS permissions to deploy functions deploy name --trigger-http --runtime=nodejs10 --entry-point=fname --project=project
and like I said it works fine when I run the gcloud deploy
locally so I'm not sure why this would fail. We have several cloud functions with similar deployment processes set up so it seems like there is something non-obvious or broken about how KMS works that avails me but perhaps it is a red herring.
If there is a better way to use KMS for this purpose, I am all ears!
Google Cloud Functions Service Agent
andCloud Build Service Account
. Do you suggest creating new service accounts? I'm not sure how to run cloud functions in the wild on arbitrary service accounts. – Barristergcloud functions deploy
call or something. Have you looked at github.com/sethvargo/secrets-in-serverless and github.com/GoogleCloudPlatform/berglas by chance? – Mungcloud functions deploy [name] --trigger-http --runtime=nodejs10 --entry-point=[name] --project=[project]
is my deploy command on both cloud build and local. I will review the above resources and let you know if I can get it to work. It seems unintuitive that GCF would run as GCE service accounts by default. What would be the purpose of having the GCF accounts then? – Barrister