google-cloud-platformgoogle-cloud-functionsgoogle-cloud-rungoogle-cloud-api-gatewaygoogle-cloud-auth

Google Cloud API Gateway can't invoke Cloud Run service while using firebase auth


I am using API Gateway with firebase JWT authorisation (so that users can use google sign in) that is forwarding the requests to cloud run services and one cloud function service.

Here is how my API Gateway config looks like:

swagger: '2.0'
info:
  version: '1.0.0'
  title: 'BFF'
  description: Backend For Frontend
schemes:
  - https
security:
  - firebase: []
securityDefinitions: 
  firebase:
    authorizationUrl: ""
    flow: "implicit"
    type: "oauth2"
    x-google-issuer: "https://securetoken.google.com/${PROJECT}"
    x-google-jwks_uri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com"
    x-google-audiences: ${PROJECT}
paths:
  /test/auth:
    post:
      operationId: testAuth
      summary: Test auth
      produces:
        - application/json
      x-google-backend:
        address: https://${REGION}-${PROJECT}.cloudfunctions.net/auth-test
      responses:
        '200':
          description: 'Response returns user related data from JWT'
  /record/new:
    post:
      operationId: crateRecord
      summary: Create new record
      x-google-backend:
        address: ${RUN_SERVICE_URL}:${RUN_SERVICE_PORT}/new
      produces:
      - application/json
      parameters:
        - in: body
          name: data
          description: Data for new record
          schema:
            $ref: '#/definitions/Record'
      responses:
        '200':
          description: New record data
          schema:
              $ref: '#/definitions/Record'
        '400':
          description: Invalid input data

The problem is that API Gateway for some reason can't invoke cloud run service but it can invoke cloud functions:

            ┍ Client is passing authorization token in header
            |
            |            ┍ Auth is successful and request is forwarded to cloud run 
            |            |
            |            |           ┍ 401 unauthorized to invoke cloud run
            |            |           |
            ↓            ↓           ↓
Client -----------> API Gateway -----X-----> Cloud run service

API Gateway service account has these relevant roles: roles/cloudfunctions.invoker, roles/run.invoker and roles/iam.serviceAccountUser

Run service also has IAM binding for gateway service account with the role roles/run.invoker

When I use /test/auth route I can see that firebase auth is working as expected and I can trigger cloud functions without any problem and in response cloud function returns data from x-apigateway-api-userinfo as expected. But when i make request with same authorization token to run service route /record/new I get:

www-authenticate: Bearer error="invalid_token" error_description="The access token could not be verified"

401 Unauthorized

Your client does not have permission to the requested URL /new.

I am running out of ideas on what might be the problem, any advice would be helpful.


Solution

  • With Cloud Functions, the identity token created contains automatically the correct audience. It's not the case when you invoke Cloud Run, you have to explicitly mention the Cloud Run audience

      /record/new:
        post:
          operationId: crateRecord
          summary: Create new record
          x-google-backend:
            address: ${RUN_SERVICE_URL}:${RUN_SERVICE_PORT}/new
            jwt_audience: ${RUN_SERVICE_URL}
    
    

    Have a try, it should work now.