I'm trying to use API Gateway in front of Cloud Functions, but getting a 401 response when the Cloud Functions are not publicly accessible.
I set the Gateway to use the default AppEngine service account identity (project-id@appspot.gserviceaccount.com), and gave the service account the Cloud Functions Invoker role in IAM. I can also see it among the invokers under the Cloud Functions Permissions tab. When the Gateway endpoint is invoked, I get a 401 response with a poorly formatted HTML payload that says "Your client does not have permission to the requested URL [url]". Unfortunately the Gateway logs are also not indicating what is the problem. When I make the Cloud Function public and wait a few minutes, the call succeeds.
I have read the "Securing backend services" section of the Guide a few times and can't see what I'm missing.
ps: This is not a JWT issue, that part works brilliantly
Found the root of the problem: it's the aud claim in the internal JWT. I wanted to leverage the flexible addressability of Cloud Functions, e.g. that a function called a handles every request that starts with a/.... In my example, the function is called hello and I want to invoke it as /hello/example from the Gateway.
The internal JWT sets the Audience claim to the address given in the OpenAPI specs (https://...cloudfunctions.net/hello/example), which does not exactly match the base URL of the Cloud Function (which is only https://...cloudfunctions.net/hello). Therefore, the Cloud Functions authorizer rejects the JWT, even though the Audience is a valid URL that is actually served by this function.
The obvious solution is to not use the variable postfix when calling Cloud Functions from the API Gateway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With