My architecture is:
- I have bunch of cloud functions (firebase)
- I have setup a ESPv2 based cloud endpoints setup with cloud run with the cloud functions as backend
- I have a SPA running on firebase hosting which is making calls to the endpoints (15 api endpoints)
- For now the APIs (cloud endpoints) are secured via APIKey (restricted)
I want make the cloud functions secured such that only the cloud endpoints (or other services within my project) can make calls to it. Directly calling the fqdns of these cloud functions should yield 403/4xx.
How do I achieve this? Is there any way?
** I don’t have organisation account so creating a service perimeter isn’t an option.
EDIT
I have accepted guillaume blaquiere's ans as the correct one. Although the ans the did not solve the issue I was facing but it is the correct ans to the question I asked.
In case anyone facing similar issue, my biggest mistake (and I wasted 1 day behind it) was with 'x-google-backend > address'. I was using only the FQDN of the cloud function not the entire URL. So This is wrong:
/myfunction/mymodule1/dosomething:
post:
summary: I command you to do something
operationId: doSomething
x-google-backend:
address: https://xxxxxxxx.cloudfunctions.net
path_translation: APPEND_PATH_TO_ADDRESS
parameters:
- name: someheaderparam
in: header
description: shhh
required: true
type: string
- name: payload
in: body
description: playload
required: false
schema:
type: object
responses:
'200':
description: OK
schema:
type: object
'401':
$ref: '#/responses/UnauthorizedError'
For this to work I needed to use the entire url of the function not just FQDN.
I my case my firebase/cloud function was an express app where I had published the function like this
exports.myfunction = functions.https.onRequest(app);
So the name of the cloudfunction is myfunction and its base url is:
https://xxxxxxxx.cloudfunctions.net/myfunction
Using express I added several paths to it, such as
app.post('/mymodule1/dosomething', validateToken(), somemethod);
If my function were to be publicly accessible, in order to invoke 'somemethod' function the url would have been:
https://xxxxxxxx.cloudfunctions.net/myfunction/mymodule1/dosomething
In order to have this mapped using openAPI behind api gateway the specification looks like this:
/mymodule1/dosomething:
post:
summary: I command you to do something
operationId: doSomething
x-google-backend:
address: https://xxxxxxxx.cloudfunctions.net/myfunction
path_translation: APPEND_PATH_TO_ADDRESS
parameters:
- name: someheaderparam
in: header
description: shhh
required: true
type: string
- name: payload
in: body
description: playload
required: false
schema:
type: object
responses:
'200':
description: OK
schema:
type: object
'401':
$ref: '#/responses/UnauthorizedError'
This is also true even if the function is not an express app. In the openAPI specification, the x-google-backend address must be the URL of the function not just the FQDN of the cloud function.
Error: Unauthorized
Your client does not have permission to the requested URL
" when I call "https://xxx-xxxx-uc.a.run.app/api/myapiname". I get 403 "Error: Forbidden" when I call cloud function url directly "https://xxxx-xxxx.cloudfunctions.net/api/myapiname". What else can I try? – Ali Nahid Nov 24 '20 at 21:27