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

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

<p>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?</p>

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

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

Andrey
<blockquote>
  <p>check if there is a built-in solution in Kubernetes</p>
</blockquote>

<p>Nope, there's no built-in solution for L7 network policies. <a href="https://kubernetes.io/docs/concepts/services-networking/network-policies/" rel="nofollow noreferrer">Network Policies</a> 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 <a href="https://linkerd.io/" rel="nofollow noreferrer">Linkerd</a>, <a href="https://istio.io/" rel="nofollow noreferrer">Istio</a> or even using a different CNI plugin based on <code>eBPF</code> such as <a href="https://cilium.io/blog/2018/09/19/kubernetes-network-policies/" rel="nofollow noreferrer">Cilium</a>.</p>

<p>Cilium has a CRD <code>CiliumNetworkPolicy</code> 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 <code>/admin</code> endpoint on any pod with label <code>app: customapp</code> and would only allow it from a pod with label <code>app: proxyapp</code>. </p>

<pre><code>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"
</code></pre>
