Path-based authorization for microservices in kubernetes

2/17/2020

I am tasked with migrating AWS lambda microservices to Kubernetes. For simplicity, there are two service endpoints: /admin and /user where you can GET or POST a request to get something done.

You have to be in admin group (defined in an external authZ provider) to hit /admin endpoint, or otherwise, you get 401. You have to be in user group to have access to /user endpoint.

I will have each endpoint exposed as a service running in a docker container. The question is - what is the correct way to add routing and path-based authorization in Kubernetes?

Like, if I go to /admin in the browser, I need Kubernetes to check if I am in admin group and then route me to admin service; otherwise, it should return 401.

I can write this router myself, but I want to check if there is a built-in solution in Kubernetes for that.

-- Andrey
authorization
kubernetes
kubernetes-ingress

2 Answers

2/18/2020

You can explore istio's traffic management. They provide routing based on user identity (https://istio.io/docs/tasks/traffic-management/request-routing/#route-based-on-user-identity). But they do this by finding the user from request header. If you have an admin group then not sure whether this can be used as is.

Sample virtual service:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
  ...
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1

The above service can be accessed from outside the cluster using istio gateway.

-- anmol agrawal
Source: StackOverflow

2/18/2020

check if there is a built-in solution in Kubernetes

Nope, there's no built-in solution for L7 network policies. Network Policies in Kubernetes are at L4 level, so things like rate limiting, path based firewall rules etc are not possible. Although you could look into a Service Mesh, like Linkerd, Istio or even using a different CNI plugin based on eBPF such as Cilium.

Cilium has a CRD CiliumNetworkPolicy which would help you with your usecase. You can put any proxy like Nginx/Caddy/HAProxy in front of it or an API Gateway like Kong, if you want to offload the authentication/authorization process. You can apply the following network policy, which would restrict the /admin endpoint on any pod with label app: customapp and would only allow it from a pod with label app: proxyapp.

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "allow-from-proxy"
specs:
  - endpointSelector:
      matchLabels:
        app: customapp
    ingress:
    - fromEndpoints:
      - matchLabels:
          app: proxyapp
      toPorts:
      - ports:
        - port: "8080"
          protocol: "TCP"
        rules:
          http:
          - method: "GET"
            path: "/admin"
-- mr-karan
Source: StackOverflow