Serverless

What's the key to a more secure Cloud Function? It's a secret!

introducing-secret-manager-blog-hero.png

Google Cloud Functions provides a simple and intuitive developer experience to execute code from Google Cloud, Firebase, Google Assistant, or any web, mobile, or backend application. Oftentimes that code needs secrets—like API keys, passwords, or certificates—to authenticate to or invoke upstream APIs and services.

While Google Secret Manager is a fully-managed, secure, and convenient storage system for such secrets, developers have historically leveraged environment variables or the filesystem for managing secrets in Cloud Functions. This was largely because integrating with Secret Manager required developers to write custom code... until now. We listened to customer feedback and today we are announcing Cloud Functions has a native integration with Secret Manager!

This native integration has many key benefits including:

  • Zero required code changes. Cloud functions that already consume secrets via environment variables or files bundled with the source upload simply require an additional flag during deployment. The Cloud Functions service resolves and injects the secrets at runtime and the plaintext values are only visible inside the process.

  • Easy environment separation. It's easy to use the same codebase across multiple environments, e.g., dev, staging, and prod, because the secrets are decoupled from the code and are resolved at runtime.

  • Supports the 12-factor app pattern. Because secrets can be injected into environment variables at runtime, the native integration supports the 12-factor pattern while providing stronger security guarantees.

  • Centralized secret storage, access, and auditing. Leveraging Secret Manager as the centralized secrets management solution enables easy management of access controls, auditing, and access logs.

Cloud Functions’ native integration with Secret Manager is available in preview to all Google Cloud customers today. Let's take a deeper dive into this new integration.

Example

Suppose the following cloud function invoked via HTTP uses a secret token to invoke an upstream API:

  const https = require('https');
const token = process.env.TOKEN;

exports.secretDemo = (req, res) => {
  https.get(`https://upstream-api.example.com?token=${token}`, (innerRes) => {
    innerRes.on('end', () => { res.send('OK') });
  }).on('error', (err) => {
    res.send(`Error: ${err}`);
  });
}

Without Cloud Functions’ native integration with Secret Manager, this function is deployed via:

  $ gcloud functions deploy "secretDemo" \
    --runtime "nodejs14" \
    --trigger-http \
    --allow-unauthenticated \
    --set-env-vars "TOKEN=abcd1234"

This approach has a number of drawbacks, the biggest of which being that anyone with viewer permissions on the Google Cloud project can see the environment variables set on a cloud function.

To improve the security of this code, migrate the secret to Secret Manager in the same project:

  $ gcloud secrets create "my_token" \
    --replication-policy "automatic" \
    --data-file - <<< "abcd1234"

Finally, without changing any code in the function re-deploy with slightly different flags:

  $ gcloud beta functions deploy "secretDemo" \
    --runtime "nodejs14" \
    --trigger-http \
    --allow-unauthenticated \
    --set-secrets "TOKEN=my_token:latest"

It's truly that easy to migrate from hard-coded secrets to using secure secret storage with Secret Manager! To add even more layers of security, consider running each cloud function with a dedicated service account and practice the principle of least privilege. Learn more in the Secret Manager Best Practices guide.

Making security easy

Security and proper secrets management are core pillars of modern software development, and we're excited to provide customers a way to improve the security of their cloud functions. To learn more about the new native integration, check out the Cloud Functions documentation. You can also learn more about Cloud Functions or learn more about Secret Manager.