Damandroid
Damandroid

Reputation: 984

How can I restrict access to my cloud functions?

I have a few cloud functions. I also have a nodejs server running in AppEngine. I make calls to my cloud functions from there. Currently I can make calls to my cloud function from anywhere!

Is there any way I can restrict access to my cloud functions to only available when called from my server running on Google App Engine?

Upvotes: 2

Views: 1518

Answers (2)

guillaume blaquiere
guillaume blaquiere

Reputation: 76018

You have 2 solutions

  1. The first one is to use a service account as described be AndresMijares. But, not to create a new one. Indeed, if you create a new service account and you want to use it with app engine, you need to generate a service account key file and to deploy this secret with your code. It's not very secure because you need also to store securely this secret and so on.

So, the solution is to use the App Engine default service account which as this email pattern

<project_ID>@appspot.gserviceaccount.com

Grant this service account as role/cloudfunctions.invoker on all the functions to invoke at the project level.


  1. The 2nd solution isn't so great as the first one but it's also possible. You can update your Cloud Functions and set the ingress parameter to internal. That means only the traffic coming from your VPCs in the project will be able to reach the Cloud Functions, included the other resources of your project (like Compute Engine). -> That's why it's not a very good solution, but at the end, Cloud Functions can't be invoked from anywhere.

So, to allow App Engin to use your VPC to call the Cloud Function, you need to use a serverless VPC connector that bridge the serverless world with your VPC. In addition to be less secure, this solution involve additional cost for the serverless VPC connector.


The advantage in the 2nd solution is that you don't have to update your application code to perform a secure call to you cloud function. You only update the deployment configuration and you have function callable only internally.

For the first solution, you need to update your code to add a security token to your request's header. It's similar to the function to function authentication. I personally don't like this way to implement that because you can't test locally: locally you don't have metadata servers!

I wrote an article from where you can get inspiration of the part "Avoid metadata server".


EDIT 1

After a deep dive in App Engine serverless VPC connector and this answer, it's only possible to reach a ingress "internal only" Cloud Function (or Cloud Run), with a Cloud Functions or Cloud run. App Engine doesn't route the public traffic inside the serverless VPC connector and thus the 2nd solution isn't possible in App Engine case.

Upvotes: 3

andresmijares
andresmijares

Reputation: 3744

There are a few ways to do this. You can create a Service Account IAM & Admin -> Services accounts

You need to apply the Cloud Functions Invoker role to this service account, you can use the gcloud cli for this.

gcloud beta functions add-iam-policy-binding YOUCLOUDFUNCTIONAME --member serviceAccount:NAME-OF-YOUR-SERVICE-ACCOUNT@project-name.iam.gserviceaccount.com --role roles/cloudfunctions.invoker --region YOUR-REGION

you will be prompted with a message like this:

bindings:
- members:
  - allUsers
  - YOUR SERVICE ACCOUNT

Ideally, you need to remove the allUsers role.

gcloud beta functions remove-iam-policy-binding YOUFUNCTIONNAME --member allUsers --role roles/cloudfunctions.invoker --region us-central1

Then you need to make sure your AppEngine instances have access to the service account you just created, that should do the trick. Be aware you might need more configuration based on your case, but this can give you a good starting point.

Upvotes: 2

Related Questions