1
votes

I've followed the google cloud endpoints with Google Kubernetes engine tutorial here: https://cloud.google.com/endpoints/docs/openapi/get-started-kubernetes-engine using my own docker image. The Kubernetes part works fine and I can access my services via the loadbalancer IP.

However, when I try to put my service behind cloud endpoints in order to secure it, the endpoint remains public and can be accessed without an API key. Here is my openapi.yaml, deployed with gcloud endpoints services deploy openapi.yaml:

swagger: "2.0"
info:
  description: "A test."
  title: "API test"
  version: "1.0.0"
host: "<test-api.endpoints.MY-PROJECT-ID.cloud.goog>"
x-google-endpoints:
- name: "<test-api.endpoints.MY-PROJECT-ID.cloud.goog>"
  target: "<MY LOADBALANCER IP>"
#require an API key to access project
security:
  - api_key: []
paths:
  /:
    get:
      summary: Return django REST default page
      description: test
      operationId: test
      responses:
        "200":
          description: OK
securityDefinitions:
  # This section configures basic authentication with an API key.
  api_key:
    type: "apiKey"
    name: "key"
    in: "query" 

When I try to access my service via the value for host (obscured because it is still open), it is still open and does not require an API key . Nothing is shown in the cloud endpoints logs either. As far as I understand, the configuration of openapi.yaml alone should be enough to restrict access?

1
Are you sure you are exposing the proxy (ESP) in your kubernetes service and not your backend directly? Please share your kubernetes service spec.nareddyt
@nareddyt I've fixed it now and that was exactly the case. It kind of glossed over it in the google guide (cloud.google.com/endpoints/docs/openapi/get-started-kubernetes), but the Kubernetes deployment script pulls an ESP image, which it uses to receive incoming API calls and redirect them to services running in other containers.millsy

1 Answers

0
votes

Following this page (https://swagger.io/docs/specification/2-0/authentication/api-keys/), your security is misplaced. It should looks like this:

swagger: "2.0"
info:
  description: "A test."
  title: "API test"
  version: "1.0.0"
host: "<test-api.endpoints.MY-PROJECT-ID.cloud.goog>"
x-google-endpoints:
- name: "<test-api.endpoints.MY-PROJECT-ID.cloud.goog>"
  target: "<MY LOADBALANCER IP>"
#require an API key to access project
paths:
  /:
    get:
      security:
        - api_key: []
      summary: Return django REST default page
      description: test
      operationId: test
      responses:
        "200":
          description: OK
securityDefinitions:
  # This section configures basic authentication with an API key.
  api_key:
    type: "apiKey"
    name: "key"
    in: "query" 

Edit:

In case you want the api-key in the header, you have to change the definition but you can leave security in the place you declared:

swagger: "2.0"
info:
  description: "A test."
  title: "API test"
  version: "1.0.0"
host: "<test-api.endpoints.MY-PROJECT-ID.cloud.goog>"
x-google-endpoints:
- name: "<test-api.endpoints.MY-PROJECT-ID.cloud.goog>"
  target: "<MY LOADBALANCER IP>"
#require an API key to access project
security:
  - api_key: []
paths:
  /:
    get:
      summary: Return django REST default page
      description: test
      operationId: test
      responses:
        "200":
          description: OK
securityDefinitions:
  # This section configures basic authentication with an API key.
  api_key:
    type: "apiKey"
    name: "key"
    in: "header" 

I didn't understand which version you preferred, so I adjusted both.