Search code examples
google-cloud-platformgoogle-cloud-rungoogle-cloud-api-gateway

Google Cloud API Gateway API Key Authentication Not Working


I've been having some trouble getting my API to work only with API key authentication. I have deployed a Cloud Run app for a simple flask API that returns "hello world", requiring authentication. I then created an API on the API Gateway, with an API config that specifies to use an API key. I suspect the API config has a mistake in it that I don't see, causing the API to be accessible without an API key. Accessing the app URL (https://flask-test-abcd1234.a.run.app/hi) directly will return "Error: Forbidden" as expected after specifying to disallow unauthenticated requests. However, the API gateway url (https://gatename-abcde123.nw.gateway.dev/hi) will return the API response without needing to add an ?api_key= query to the URL. Any help is greatly appreciated. Edit: I had created a service account with the cloud run invoker role as well.

Deployed cloud run app:

from flask import Flask

app = Flask(__name__)

@App.route('/hi', methods=['GET'])
def hello_world():
    return 'Hello, World?'

if __name__ == '__main__':
    app.run(debug=True)

API config .yaml file:

# openapi2-run.yaml
swagger: "2.0"
info:
  title: Sample Flask API d
  description: A simple API for demonstration
  version: 1.0.0
host: test-api.apigateway.projectname.cloud.goog
schemes:
  - https
produces:
- application/json
security:
  - api_key: []
x-google-backend:
  address: >-
    https://test-abcd1234-nw.a.run.app
x-google-management:
  metrics:
    - name: "get-requests"
      displayName: "get requests"
      valueType: INT64
      metricKind: DELTA
  quota:
    limits:
      - name: "get-limit"
        metric: "get-requests"
        unit: "1/min/{project}"
        values:
          STANDARD: 1000
paths:
  /hi:
    get:
      summary: Get hello
      operationId: getHi
      security: []
      parameters: []
      responses:
        200:
          description: A successful response
          schema:
            type: string
securityDefinitions:
  api_key:
    type: apiKey
    name: key
    in: query
definitions:
  User:
    type: object
    properties:
      username:
        type: string
      firstname:
        type: string
      lastname:
        type: string
      email:
        type: string

Solution

  • I have replicated your issue with the same yaml file and I was getting the same behavior. I have updated part of your config file and now I am able to access the page only when add API keys as query with URL i.e ?key=API_KEY.

    Here is the updated part

    paths:
      /hi:
        get:
          summary: Get hello
          operationId: getHi
          security:
             - api_key: []
          x-google-quota:
            metricCosts:
              "get-requests": 1
          parameters: []
          responses:
            200:
              description: "successful operation"
              schema:
                type: "array"
                items:
                  $ref: "#/definitions/User"