1

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.

Šime
  • 139
  • 6

1 Answers1

7

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.

guillaume blaquiere
  • 66,369
  • 2
  • 47
  • 76
  • Bro thank you so much, I was losing my mind for 3 days without success and this simple solution solved everything. I know about `jwt_audience` param but I ignored it since in documentation it says: [If an operation uses x-google-backend but does not specify either jwt_audience or disable_auth, ESPv2 will automatically default the jwt_audience to match the address.](https://cloud.google.com/endpoints/docs/openapi/openapi-extensions#jwt_audience_disable_auth) – Šime Apr 07 '22 at 14:46