I have a simple cloud function...
import functions from "@google-cloud/functions-framework";
const protectedExample = (req, res) => {
res.send('Protected example');
};
functions.http('protectedExample', protectedExample);
export {protectedExample}
Then I protect it using my API...
swagger: '2.0'
info:
title: hw-api Gateway
description: Sample API Gateway
version: 1.0.1
securityDefinitions:
auth0:
type: oauth2
flow: implicit
x-google-issuer: https://.../
x-google-jwks_uri: https://.../.well-known/jwks.json
x-google-audiences: https://.../node
authorizationUrl: https://.../authorize
scopes:
"access:node": Grants read access
schemes:
- https
produces:
- application/json
paths:
/protected:
get:
security:
- auth0: [ "access:node" ]
summary: Greet a user
operationId: hello
x-google-backend:
address: https://us-central1-....cloudfunctions.net/protectedExample
responses:
'200':
description: A successful response
schema:
type: string
This works great from an API perspective, however, when I run the following...
gcloud functions describe protectedExample
then try to call the endpoint described by
httpsTrigger:
securityLevel: SECURE_ALWAYS
url: https://us-central1-....cloudfunctions.net/protectedExample
I can still access the function. How do I prevent external people from accessing it except through the Gateway?
I tried --ingress-settings=internal-and-gclb
but then I get
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Forbidden</h1>
<h2>Access is forbidden.</h2>
<h2></h2>
</body>
When I try to call it through the Gateway.
In order to make the Cloud Function endpoint private but still accessible to the API Gateway, you have to give the API Gateway service account the roles/cloudfunctions.invoker
role, and that the gateway's service account has the cloudfunctions.functions.invoke
permission.
Make sure to also remove the allUsers
role from the permissions list for the Cloud Function or deploy your Cloud Functions securely by setting the param to --no-allow-unauthenticated
.