3

I have successfully deployed a Cloud Function that does some basic pre-processing to some data and uploads it to gSheet.
Now, the trigger url accepts external unauthenticated invocations, leading to the risk of excessive bills in case the url ends up in the wrong hands.

I am wondering if there's any way to restrict invocation to Cloud Scheduler in IAM, preventing external calls to the service altoghether.
Reading around it seems that including some header in the request and checking for it in the function could be a rudimental way to enforce really basic authenthication.

anddt
  • 1,589
  • 1
  • 9
  • 26

2 Answers2

9

For preventing, external uneuthenticated call, you can set you function private. Very easy to do, deploy it with the --no-allow-unauthenticated param

gcloud functions deploy my-function --no-allow-unauthenticated --trigger... -- region... --runtime...

But now, the scheduler can't call it. Now you have to perform 2 things

  • Create a service account with the correct roles. You can do it by the GUI or with command line
# Create the service account
gcloud iam service-accounts create your-service-account-name

# Grant the role for calling the function
gcloud functions add-iam-policy-binding \
  --member=serviceAccount:your-service-account-name@YOUR_PROJECT_ID.iam.gserviceaccount.com \
  --role=roles/cloudfunctions.invoker your-function-name

With the GUI, if you grant the role cloudfunctions.invoker at project level, your service account will be able to access to all function in your project. With my command line, I only grant the role on a specific function. You can do it through the console, by going to the functions list, select a function (check box) and click on show info panel. Here you have a permission tab

  • Then create your scheduler with the service account
gcloud scheduler jobs create http your-job name --schedule="0 0 * * *" \
  --uri=your-function-URI \
  --oidc-service-account-email=your-service-account-name@YOUR_PROJECT_ID.iam.gserviceaccount.com

If it doesn't work, it's because your cloud scheduler service agent isn't authorize to generate token with service account.

gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
  --member=serviceAccount:service-[project-number]@gcp-sa-cloudscheduler.iam.gserviceaccount.com \
  --role roles/cloudscheduler.serviceAgent
guillaume blaquiere
  • 66,369
  • 2
  • 47
  • 76
  • Thanks guillaume for the exhaustive reply. Another **very** naive solution (to be baked in the python script) would be to check for some value in the request header before executing any job. No idea if it represents a risk from a security perspective (the request would be on `https` anyway). – anddt Jan 30 '20 at 10:03
  • 1
    It represents 2 risks: First, the header is checked by your function, and you are charged on this processing time. If there is a huge number of request, your billing explode. Second, the security is lower in case of man in the middle. With JWT token, if the token is stolen, his life duration is short (5 minutes in general). If your header value is stolen, with which frequency do you update it? You can have a look on API Key security method, it's the same concern. – guillaume blaquiere Jan 30 '20 at 13:21
  • Thanks for pointing it out. I'm accepting this answer as it worked like a charm. Apart from figuring out how to deploy a branch different from `master` everything took literally five minutes. – anddt Feb 04 '20 at 14:06
  • Happy to help! :) – guillaume blaquiere Feb 04 '20 at 22:36
0

If you want to restrict access to your Google Cloud Functions from end-user requests, you can integrate Google Sign-In with Cloud IAM or implement Firebase Authentication

Cloud Functions: Authenticating Developers, Functions, and End-users:

Most applications handle requests from end-users, and it's a best practice to restrict access to only allowed end users. In order to accomplish this, you can integrate Google Sign-In and grant users the roles/cloudfunctions.invoker IAM role, or implement Firebase Authentication and manually validate their credentials.

marian.vladoi
  • 7,663
  • 1
  • 15
  • 29