In this how-to article, I’m going to show how you can secure your Google Cloud Platform (GCP) Functions HTTP trigger, it has not been that straightforward to secure HTTP trigger in Cloud Functions in the past HTTP triggers in GCP were publicly available. While this might be useful in a lot of scenarios, it’s also quite possible you don’t want ‘strangers’ hitting your public endpoints all the time.
If you read on, I will show how to remove an unauthorized Cloud Function HTTP Trigger, and how you can create a service account to be used with your application to trigger the Cloud Function HTTP URL or in my example using Cloud Scheduler to trigger, the HTTP Trigger URL is your endpoint to your Cloud Function.
Cloud Function Dashboard
When you create a Cloud Function with an HTTP trigger, if your use case is to allow an unauthenticated HTTP trigger, then you do not need to do anything. If your use case is to secure the HTTP trigger so you can control who can access the HTTP trigger, then read on.
In your Cloud Functions dashboard, in the column Authentication, you can find what Authentication status your function has. If it says Allow unauthenticated, then your Cloud Function is open to the public internet, which means that anyone could trigger your cloud function if they have the URL to the cloud function.
If you care about security then your Cloud Function should be authenticated and your dashboard should look like this.
Cloud Function Trigger
In the Cloud Function, you will find your URL trigger under the label TRIGGER, as shown below.
If you have Cloud Function that is set to Allow unauthenticated, it is very simple to change – click on the Cloud Function name from the Cloud Function Dashboard that opens up details about your Cloud Function, choose permissions and then Cloud Functions Invoker from the list of Roles – if you have an allUsers Role that means your Cloud Function is unauthenticated, to make it authenticated just delete the allUsers from your Cloud Functions permissions.
Cloud IAM & Admin
Here are the steps to make Cloud Scheduler trigger an HTTP triggered Cloud Function that doesn’t allow unauthenticated invocations: Create a service account, which will have the following form [SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com.
Add the service account [SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com as a project member and add the following roles to the service account: Cloud Functions Invoker, Secret Manager Admin, Cloud Build Admin, Firebase Admin and Cloud Scheduler Admin.
Add Service Account to Cloud Function
Deploy an HTTP triggered Cloud Function that doesn’t allow public (unauthenticated) access and that used the recently created service account [SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com on the Service account field (click more and look for the Service account field, by default it should be set to the App Engine default service account) and take notice of the Cloud Function’s URL.
Tying it up with Cloud Scheduler
Create a Cloud Scheduler job with authentication by issuing the following command from the Cloud Shell:
gcloud scheduler jobs create http getNews --schedule="0 10 * * *" --uri=<function Trigger URL> --oidc-service-account-email=<service-account>
If you have to edit an old cloud schedule to trigger an Authenticated – you need to apply authentication to the Cloud trigger to a service account that is associated with your Cloud Function. To do this, you apply OIDC token – you can edit your cloud schedule entry and add an OIDC token.
Do not run this gcloud command as it will set allUsers making your cloud functions all unauthorized
"gcloud functions add-iam-policy-binding <function name> --region=<region> --member=allUsers --role=roles/cloudfunctions.invoker"
If you deploy your Cloud Function from the command line with gcloud – do not include –allow-unauthenticated your cloud command should look like something like this
gcloud functions deploy getNews_http --runtime python37 --trigger-http --region=europe-west1 --memory=128MB
If you deploy using Google Cloud Build, you should not include –allow-unauthenticated, it should look something likes this your cloudbuild.yaml file
steps: - name: "gcr.io/cloud-builders/gcloud" waitFor: ["-"] args: - functions - deploy - getNewsGuardian_http - --runtime=python37 - --trigger-http - --region=europe-west1 - --memory=512MB - --timeout=240 id: "deploying-serverless-guardian_bot" dir: "socialclimatetech-news-guardian"
That is it, I hope it was clear and that you know have the knowledge of applying this to your Cloud Functions. As always I look for feedback, please add your comments below.