Skip to content

Instantly share code, notes, and snippets.

@atomatt
Last active September 6, 2021 14:27
Show Gist options
  • Select an option

  • Save atomatt/d41acca0fb02842d624314f228026cb1 to your computer and use it in GitHub Desktop.

Select an option

Save atomatt/d41acca0fb02842d624314f228026cb1 to your computer and use it in GitHub Desktop.
Kong auth proxy for Kubernetes service

A HTTP API, purely to demo. Normally, it would not be accessible inside the cluster (remove the type: NodePort).

apiVersion: apps/v1
kind: Deployment
metadata:
  name: http-api
spec:
  selector:
    matchLabels:
      app: http-api
  template:
    metadata:
      labels:
        app: http-api
    spec:
      containers:
      - name: http-api
        image: hashicorp/http-echo
        ports:
        - containerPort: 5678
        args:
        - -text
        - "Hello!"
---
apiVersion: v1
kind: Service
metadata:
  name: http-api
spec:
  type: NodePort
  selector:
    app: http-api
  ports:
  - port: 80
    targetPort: 5678

We also need an authenticating proxy, implemented using a database-less Kong with API keys.

The interesting bit is the secret/http-api-auth-proxy-config resource; the rest is boilerplate. Ideally, the secret would be split up so only the consumers were in a Secret (because they're probably managed by someone else) with the rest in a ConfigMap.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: http-api-auth-proxy
spec:
  selector:
    matchLabels:
      app: http-api-auth-proxy
  template:
    metadata:
      labels:
        app: http-api-auth-proxy
    spec:
      automountServiceAccountToken: false
      containers:
      - name: "proxy"
        image: kong:2.5
        env:
        - name: KONG_DATABASE
          value: "off"
        - name: KONG_ADMIN_ACCESS_LOG
          value: "/dev/stdout"
        - name: KONG_ADMIN_ERROR_LOG
          value: "/dev/stderr"
        - name: KONG_PROXY_ACCESS_LOG
          value: "/dev/stdout"
        - name: KONG_PROXY_ERROR_LOG
          value: "/dev/stderr"
        - name: KONG_DECLARATIVE_CONFIG
          value: /home/kong/kong.yaml
        ports:
        - containerPort: 8000
        volumeMounts:
          - name: kong-kong-prefix-dir
            mountPath: /kong_prefix/
          - name: kong-kong-tmp
            mountPath: /tmp
          - name: kong-custom-dbless-config-volume
            mountPath: /home/kong/
      volumes:
        - name: kong-kong-prefix-dir
          emptyDir: {}
        - name: kong-kong-tmp
          emptyDir: {}
        - name: kong-custom-dbless-config-volume
          secret:
            secretName: http-api-auth-proxy-config
---
apiVersion: v1
kind: Service
metadata:
  name: http-api-auth
spec:
  type: NodePort
  selector:
    app: http-api-auth-proxy
  ports:
  - name: http
    port: 8000
---
apiVersion: v1
kind: Secret
metadata:
  name: http-api-auth-proxy-config
stringData:
  kong.yaml: |
    _format_version: "2.1"

    # The service we're protecting with public and private (requires api key) named routes.
    services:
    - name: http-api
      url: http://http-api
      routes:
      - name: http-api-public
        paths:
        - /
      - name: http-api-private
        paths:
        - /api
        plugins:
        - name: key-auth

    # Require a consumer in the `http-api-full` group when accessing the `http-api-private` route.
    plugins:
    - name: acl
      route: http-api-private
      config:
        allow:
        - http-api-full
        hide_groups_header: false

    # A couple of consumers (for fun, one has a rotated key)
    consumers:
    - username: alice
      keyauth_credentials:
      - key: alice-key-2
      - key: alice-key-1
    - username: bob
      keyauth_credentials:
      - key: bob-key-1

    # Only one of the consumers is in the `http-api-full`
    acls:
    - consumer: alice
      group: http-api-full

Accessing the service directly, nothing is protected.

~ xh $(minikube service --url http-api)/
HTTP/1.1 200 OK
Content-Length: 7
Content-Type: text/plain; charset=utf-8
Date: Mon, 06 Sep 2021 14:20:07 GMT
X-App-Name: http-echo
X-App-Version: 0.2.3

Hello!~ xh $(minikube service --url http-api)/api
HTTP/1.1 200 OK
Content-Length: 7
Content-Type: text/plain; charset=utf-8
Date: Mon, 06 Sep 2021 14:20:14 GMT
X-App-Name: http-echo
X-App-Version: 0.2.3

Hello!

But going through the Kong proxy, public endpoints are available while private endpoints require a user in the http-api-full group.

~ xh $(minikube service --url http-api-auth)/
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 7
Content-Type: text/plain; charset=utf-8
Date: Mon, 06 Sep 2021 14:21:31 GMT
Via: kong/2.5.0
X-App-Name: http-echo
X-App-Version: 0.2.3
X-Kong-Proxy-Latency: 165
X-Kong-Upstream-Latency: 1

Hello!~ xh $(minikube service --url http-api-auth)/api
HTTP/1.1 401 Unauthorized
Connection: keep-alive
Content-Length: 45
Content-Type: application/json; charset=utf-8
Date: Mon, 06 Sep 2021 14:21:33 GMT
Server: kong/2.5.0
Www-Authenticate: Key realm="kong"
X-Kong-Response-Latency: 1

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


➜  ~ xh $(minikube service --url http-api-auth)/api apikey:alice-key-1
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 7
Content-Type: text/plain; charset=utf-8
Date: Mon, 06 Sep 2021 14:21:42 GMT
Via: kong/2.5.0
X-App-Name: http-echo
X-App-Version: 0.2.3
X-Kong-Proxy-Latency: 49
X-Kong-Upstream-Latency: 1

Hello!~ xh $(minikube service --url http-api-auth)/api apikey:bob-key-1  
HTTP/1.1 403 Forbidden
Connection: keep-alive
Content-Length: 49
Content-Type: application/json; charset=utf-8
Date: Mon, 06 Sep 2021 14:21:49 GMT
Server: kong/2.5.0
X-Kong-Response-Latency: 1

{
    "message": "You cannot consume this service"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment