Private paths in a public API with Kubernetes

4/3/2019

We have a microservice architecture based on Kubernetes in Amazon EKS with Ambassador as API Gateway.

We have 2 Ambassadors: 1 public and 1 private. So we have services that are only accessible by services in the cluster or VPN, and we have some services that are public.

We have the need for making private some URL paths in the public services. For example, we have a public API that is accessible in api.company.com, and we want to leave all paths public like api.company.com/createuser, api.company.com/login, etc... but for other paths we want to make them private, for example: api.company.com/swagger.html.

We know that we could enable authentication for those paths in the API, but we are looking for a solution without auth.

An example of how we configure K8s service with Ambassador for public services:

apiVersion: v1
kind: Service
metadata:
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v0
      kind:  Mapping
      name:  backends_mapping
      prefix: /
      ambassador_id: ambassador-public
      service: backends.svc:8080
      host: api.mycompany.com
  labels:
    app: backends
  name: backends
  namespace: svc
spec:
  ports:
  - name: http-backends
    port: 8080
    protocol: TCP
    targetPort: http-api
  selector:
    app: backends
  type: ClusterIP
-- Adrián
amazon-web-services
api-gateway
kubernetes

2 Answers

4/3/2019

Cilium can do just what you want:http://docs.cilium.io/en/stable/policy/language/#http

Basically you can specify L7 network policies which will only allow access to some of you API paths from certain pods.

Cilium project page: https://cilium.io/ Layer 7 policies example: http://docs.cilium.io/en/stable/policy/language/#http EKS install guide: http://docs.cilium.io/en/v1.4/gettingstarted/k8s-install-eks/?highlight=eks

Disclaimer: I am part of the team that develops Cilium.

-- Nebril
Source: StackOverflow

4/3/2019

Not sure what do you mean by without auth. You will need some sort of check to serve internal content.

One approach to achieve this can be(Note this is a high level overview).

You can make the service private, do not expose this service directly.

Prefix all your internal routes with say /internal/ or /private/ prefix.
So api.company.com/swagger.html becomes api.company.com/internal/swagger.html

You can create a load balancer that points to this middleware. Middleware(public service) will intercept all the requests. I think Nginx can be used here. If the request has /internal/ path check if it satisfies the condition(origin, internal network etc).

If the check passes, redirect to private service. If the check fails return 403 forbidden or whatever response code that fits.

-- Ankit Deshpande
Source: StackOverflow