Secure a vanilla API with Kong API gateway

Xin Cheng
2 min readNov 29, 2020

Developers want to focus more on adding the business values/features, rather than solving problems that don’t add business values. Separation of concerns is popular method to separate different sections in a software (e.g. main business logic, authentication, authorization, caching, routing, etc.). There are lots of solutions that can provide out-of-box capabilities that enable developers to write less code and focus on core features, e.g. service mesh (istio, linkerd, consul connect), api gateway (kong, ambassador), dapr.

In this article, I would like to show you how you can add api key security authentication to a vanilla API (e.g. mlflow)in Kubernetes, with Kong API gateway, which requires no code modification. In Kong-Kubernetes-way, the steps are:

  1. Install Kong API gateway
  2. Deploy vanilla API and create ingress
  3. Enable api key plugin in Kong
  4. Enable api key plugin for the application
  5. Create api key secret
  6. Create Kongconsumer for the application

Prerequisite

Create Kubernetes cluster

Install Kong API gateway

helm repo add kong https://charts.konghq.com
helm repo update
# Helm 2
helm install kong/kong
# Helm 3
helm install kong/kong --generate-name --set ingressController.installCRDs=false

Deploy vanilla API and create ingress rule

kubectl apply -f https://bit.ly/k8s-httpbin
service/httpbin created
deployment.apps/httpbin created

create ingress rule

echo '
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: demo
annotations:
konghq.com/strip-path: "true"
kubernetes.io/ingress.class: kong
spec:
rules:
- http:
paths:
- path: /foo
backend:
serviceName: httpbin
servicePort: 80
' | kubectl apply -f -
ingress.extensions/demo created

Test API

export PROXY_NAME=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].hostname}" service -n kong kong-proxy)
curl -i $PROXY_NAME/foo

Enable api key plugin in Kong

echo "
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: httpbin-auth
plugin: key-auth
" | kubectl apply -f -

Enable api key plugin for the application

echo '
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: demo
annotations:
konghq.com/strip-path: "true"
konghq.com/plugins: httpbin-auth
kubernetes.io/ingress.class: kong
spec:
rules:
- http:
paths:
- path: /foo
backend:
serviceName: httpbin
servicePort: 80
' | kubectl apply -f -

Now curl requires api key

curl -i $PROXY_NAME/foo

{"message":"No API key found in request"}

Create api key secret

kubectl create secret generic harry-apikey  \
--from-literal=kongCredType=key-auth \
--from-literal=key=my-sooper-secret-key
secret/harry-apikey created

Notice that kongCredType is key-auth, and key is the api key.

Create Kongconsumer for the application

echo "apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
name: harry
annotations:
kubernetes.io/ingress.class: kong
username: harry" | kubectl apply -f -
kongconsumer.configuration.konghq.com/harry created

Now test with api key

curl -i -H 'apikey: my-sooper-secret-key' $PROXY_NAME/foo

--

--

Xin Cheng

Multi/Hybrid-cloud, Kubernetes, cloud-native, big data, machine learning, IoT developer/architect, 3x Azure-certified, 3x AWS-certified, 2x GCP-certified