Authenticate requests to apps on kubernetes using Nginx-Ingress and an AuthService.

A common pattern for deploying micro-services deployed on cluster, like kubernetes, is to delegate authentication to another external service or extract it out to its own micro-service on the cluster.

Micro-services Deployment on a K8s Cluster.

Delegating authentication for all API calls can be a powerful way of avoiding the need to implement some authentication plumbing at each micro-service. This frees development teams to focus more on domain logic and avoids repeat work. This article introduces nginx-ingress annotations that can help configure the required routing for such an authentication/authorisation flow.

Authentication Annotations

Nginx-Ingress is a fairly mature ingress solution for deployments on kubernetes and comes with a lot of out-of-box features. Most of them can be used by simply supplying annotations to the respective ingress yamls. For our purpose we can look at the external-auth annotations ‘auth-url’.

nginx.ingress.kubernetes.io/auth-url: "url to auth service"

This annotation tells the nginx-ingress controller to forward the incoming request first to the auth-service, and then if the auth-service responds with an 200 Ok then on to the downstream route. For example:

apiVersion: extensions/v1beta1 
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/auth-url: http://auth-service.prod.svc.cluster.local/authenticate
namespace: prod
name: ingress-with-auth
spec:
rules:
- host: api.microservice-1.myapp.com
http:
paths:
- path: /secure/
backend:
serviceName: microservice-1
servicePort: 8080

The above ingress config would instruct the nginx-ingress to forward any incoming requests on api.microservice-1.myapp.com/secure/ to the /authenticate endpoint of an auth-service deployed internally to the cluster.

  1. User/client makes an api request to api.microservice-1.myapp.com/secure/*
  2. At the Ingress controller, the same request is routed to /authenticate endpoint of the auth service
  3. If the auth-service responds with an 200 Ok the request is passed through to microservice-1

We can even extend this pattern and have the authentication service pass some information to the downstream applications using the auth-response-headers annotation. For example, the AuthService can, as part of the authentication, resolve the userName or userId for the incoming request and return them to the microservice-1:

apiVersion: extensions/v1beta1 
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/auth-url: http://auth-service.prod.svc.cluster.local/authenticate
nginx.ingress.kubernetes.io/auth-response-headers: UserID
namespace: prod
name: ingress-with-auth
spec:
rules:
- host: api.microservice-1.myapp.com
http:
paths:
- path: /secure/
backend:
serviceName: microservice-1
servicePort: 8080
  1. User/client makes an api request to api.microservice-1.myapp.com/secure/*
  2. At the Ingress controller, the same request is routed to /authenticate endpoint of the auth service
  3. Authentication service resolves UserID as part of the authentication, and appends it to the response headers
  4. Nginx-Ingress appends the UserID response header from AuthService to the request headers of the original request, and passes it through to microservice-1
Forwarding Response Headers From AuthService

Software Engineer | Technology Consultant @ ThoughtWorks.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store