Search code examples
node.jsgoogle-cloud-platformgoogle-cloud-functionsgoogle-cloud-kmsgoogle-secret-manager

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.


Solution

  • 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.