Categories
Software development

HMAC auth with Kong in Kubernetes

This may help you setup hmac-auth with Kong in Kubernetes.

There is no guide for setting up HMAC, but, the JWT guide is great. It helped me understand Kong Plugins have specific expectations for Kubernetes Secrets.

In a nutshell, Kong Plugins expect Kubernetes Secrets to (1) reference the plugin type in the kongCredType field and (2) contain literals that match the Kong Credential type supported by your intended Kong Plugin.

kubectl create secret \ 
generic a-hmac-secret -n test-namespace \ 
--from-literal=kongCredType=hmac-auth \ 
--from-literal=username=hook-user \ 
--from-literal=secret=$hmackey

To setup the HMAC plugin, your Kubernetes secret must define the kongCredType, username, and secret. The kongCredType for HMAC is hmac-auth, username is a string and gets sent by your client in the Authorization header, and secret is a string that must be known by both the client and server to do encryption and decryption. Look at the properties on the credential object here for supporting detail.

The below YAML should help you get HMAC authorization working for your Ingress using Kong Plugins. Here are some tips:

  1. This assumes you have Kong installed in your Kubernetes cluster, already, and the IP address for the Kong Proxy ingress associated with proxy.mydomain.com.
  2. We intend to protect backend-service with HMAC auth, which exists in the test-namespace.
  3. Kubernetes objects we create to support HMAC auth for this service will be created in the same namespace, test-namespace.
  4. Environment variables (things beginning with $) are known and set prior to running scripts where applicable.
  5. Watch logs from your Kong deployment to observe whether Ingress/Plugin setup has errors kubectl logs deploy/kong-kong --follow --all-containers
  6. My ingress (below) has additional configuration to support http to https redirects, and provision SSL automatically (related links are included in comments).
---
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: webhook-hmac
  namespace: test-namespace
plugin: hmac-auth
config:
  hide_credentials: true
  enforce_headers: 
  - date 
  - host
  - request-line
  algorithms: 
  - hmac-sha256
---
---
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
  name: hook-user
  namespace: test-namespace
username: hook-user
credentials:
- a-hmac-secret
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: webhook-frontend
  namespace: test-namespace
  annotations:
    konghq.com/plugins: webhook-hmac
    # https://github.com/Kong/kubernetes-ingress-controller/blob/master/docs/guides/cert-manager.md
    kubernetes.io/tls-acme: "true"
    cert-manager.io/cluster-issuer: letsencrypt-prod
    # https://github.com/Kong/kubernetes-ingress-controller/blob/master/docs/guides/configuring-https-redirect.md
    konghq.com/override: https-only
spec:
  # https://github.com/Kong/kubernetes-ingress-controller/blob/master/docs/guides/cert-manager.md
  tls:
  - secretName: proxy-mydomain-com
    hosts:
    - proxy.mydomain.com
  rules:
  - host: proxy.mydomain.com
    http:
      paths:
      - path: /my/protected/path
        backend:
          serviceName: backend-service
          servicePort: 8080 
---

Now, requests sent to https://proxy.mydomain.com/my/protected/path will require an Authorization header supporting HMAC as configured above, and if valid, be sent to the backend-service.