Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Cloud Function : support for Google Cloud KMS

I am using a Google Cloud Function (GCF) with a Pubsub trigger which sends a HTTP request to a third party API.

The GCF receives notifications from a Pubsub topic used by a service which should not be aware of the third party API.

The third party API requires an authentication using Basic HTTP Authentication.

In order to not to have to hardcode the password in my source code I am using Google KMS to generate a new encrypted key each time I deploy my function. I am using Google Cloud KMS to decrypt the secret each time the function is instantiated.

For decrypting using KMS I have to provide a private key for a service account to the NodeJS Google API.

My main problem today is that I have to push my private key to the GCloud Bucket if I want my GCF to work properly.

Is it possible by using either the Runtime Configurator or the Deployment Manager to configure secrets for a Google Cloud Function?

Thanks you.

like image 717
JackTheRipper Avatar asked Jun 12 '17 18:06

JackTheRipper


People also ask

What is Google Cloud KMS used for?

Cloud KMS is a REST API that can use a key to encrypt, decrypt, or sign data such as secrets for storage. Cloud KMS is available in several global locations and across multi-regions, allowing you to place your service where you want for low latency and high availability.

Is KMS global or regional?

Even though KMS is a global service but keys are regional that means you can't send keys outside the region in which they are created.

Is Google KMS free?

100,000 key use operations for symmetric encryption and decryption, or signing and verification. (Key admin operations are free.)


2 Answers

As of December 2019, the preferred way to store and manage secrets on Google Cloud is Secret Manager:

$ echo -n "user:pass" | gcloud beta secrets create "my-basic-auth" \
  --data-file=- \
  --replication-policy "automatic"

You can also create and manage secrets from API:

// Import the library
const {SecretManagerServiceClient} = require('@google-cloud/secret-manager');

// Create the client
const client = new SecretManagerServiceClient();

// Create the secret
const [secret] = await client.createSecret({
  parent: "projects/<YOUR-PROJECT-ID>",
  secretId:"my-basic-auth",
  secret: {
    replication: {
      automatic: {},
    },
  },
});

// Add the version with your data
const [version] = await client.addSecretVersion({
  parent: secret.name,
  payload: {
    data: Buffer.from("user:pass", "utf8"),
  },
});

Then, in your Cloud Function:

const [version] = await client.accessSecretVersion({
  name:"projects/<YOUR-PROJECT-ID>/secrets/<MY-SECRET>/versions/1",
});

const auth = version.payload.data.toString('utf-8');

// auth is user:pass

The service account with which you deploy your Cloud Function will need roles/secretmanager.secretAccessor permissions.

like image 115
sethvargo Avatar answered Oct 06 '22 15:10

sethvargo


The other solution to this which came out only in the last few months, is to use Google Cloud Runtime Configuration with Firebase for Functions: https://firebase.google.com/docs/functions/config-env

Firebase for Functions seems to provide access to several features that are not yet available via other means.

Runtime Configurator does not charge for use, but enforces the following API limits and quotas:

  • 1200 Queries Per Minute (QPM) for delete, create, and update requests
  • 600 QPM for watch requests.
  • 6000 QPM for get and list requests.
  • 4MB of data per user, which consists of all data written to the Runtime Configurator service and accompanying metadata.

https://cloud.google.com/deployment-manager/pricing-and-quotas#runtime_configurator


As an aside, I find this conflict in the Firebase for Functions comical:

The Firebase SDK for Cloud Functions offers built-in environment configuration to make it easy to store and retrieve this type of data for your project without having to redeploy your functions.

Then a moment later:

After running functions:config:set, you must redeploy functions to make the new configuration available.


The KMS solution is a viable alternative, however it seems costly for functions. KMS is billed at $0.06 per month per active key, as well as $0.03 per 10,000 operations.

This would then change the cost of your Cloud Function from $0.40 per million invocations, to $3.40 per million invocations. That is quite the jump.

  • https://cloud.google.com/kms/
  • https://cloud.google.com/functions/
like image 40
balupton Avatar answered Oct 06 '22 17:10

balupton