Invoking HTTP Google Cloud Function from Google App Engine service in the same project
“Google Cloud Functions (GCF) is a serverless execution environment for building and connecting cloud services. With Cloud Functions, you write simple, single-purpose functions that are attached to events emitted from your cloud infrastructure and services.”
To build an encryption/decryption module. Since it did not require sharing state between executions and the module was simple and single-purpose, the decision was to use GCF.
Once the cloud function is created, it uses Google Key Management Service (KMS) to encrypt and decrypt data.
It was configured to be HTTP triggered (there are other ways to trigger it) and authentication enabled (unauthenticated is the other option — it would make the function accessible to the public). Simply put, google gave an https URL which when invoked would call the cloud function if authenticated.
After the cloud function was set up, it had to be called from a GAE service in the same GCP project. They both use the default service account for the GCP project and under the same VPC. Hence, the primary assumption was, it would not need extra steps for authentication but that’s wrong!
For scalability and availability, google uses multiple servers and your request might end up in a server that does not host the cloud function even though it is in the same GCP project. So, we need to generate a google signed OAuth ID token. Here’s the official tutorial- https://cloud.google.com/functions/docs/securing/authenticating (the metadata URL is wrong though, which was figured out later).
Getting ID Token & Calling the Function
- Call http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=<your_function_url> with header Metadata-Flavor: Google(this makes sure the default service account is used)
- The received token has to be used in Authorization header, with bearer as prefix.
Here’s a sample, which is written in python-