How to access and authenticate a Google Apps Script doPost() Pub/Sub push endpoint properly?

Viewed 269

Overall flow

I'm working with Google Cloud Platform (GCP), Google Apps Script (GAS), and the Pub/Sub service within a Google Workspace domain environment. This is the flow of requests/data, which works but clearly has auth issues:

  1. GCP Pub/Sub service receives messages for a specific topic
  2. Pub/Sub forwards the message to a push endpoint URL by POST
  3. The push endpoint is a doPost() function within Google Apps Script (GAS), published as a Web App

Details

I have enabled authentication for the Service Account used in the Pub/Sub delivery type options, i.e. Pub/Sub signs a JSON Web Token (JWT) and sends the JWT in the authorization header of the push request. Edit: The Service Account (Client ID) has a domain-wide delegation for the Scopes



Web App deployments come with two options:

"Execute as"

  • Me (name@workspace-domain.tld)
  • User accessing the web app

"Who has access"

  • Only myself
  • Anyone within {workspace domain}
  • Anyone with Google account
  • Anyone

Right now, the web app executes as Me with Anyone having access. And it works.

Problems

The push endpoint is publicly accessible, but should not be. (1)

Follow-up: "The push endpoint must be a publicly accessible HTTPS address" (source) anyways, so "Who has access" will be set to "Anyone" by design.

Limiting the "Who has access" option to "anyone within {domain}" leads to unacknowledged messages inside the Pub/Sub subscription, doPost() will not run, but the endpoint returns straight 40X HTTP codes (probably forbidden).

--> Question: How can I promote the Service Account to being seen as a user within the workspace domain, so it has access to the endpoint?

The push endpoint should validate tokens sent by Pub/Sub. (2)

In GAS, doPost() has no access to (authorization) headers sent to the web app endpoint URL (unfortunately and as far as I know). However, ScriptApp.getIdentityToken() gets an OpenID Connect identity token for the effective user, if the openid scope has been granted.

--> If problem (1) was solved, is it possible to authenticate and authorize the messages send to the endpoint within the GAS doPost() function using ScriptApp.getIdentityToken()? From my understanding, the Service Account should also become the effective user, i.e. "Execute as" = "User accessing the web app".

I might be missing something. So, thanks for any tips and advice!

Doc links

Google Apps Script: Web Apps
https://developers.google.com/apps-script/guides/web

GAS: ScriptApp.getIdentityToken()
https://developers.google.com/apps-script/reference/script/script-app#getidentitytoken

Using push subscriptions: Authentication and authorization by the push endpoint
https://cloud.google.com/pubsub/docs/push#authentication_and_authorization_by_the_push_endpoint

0 Answers
Related