I write this post even though I already solved the issue, because I think it might help someone out there, since I couldn't the cause nor a solution anywhere.
I'm learning Kong authentication strategies, in particular through these plugins:
However, I've been stuck for almost an hour on a error which I wasn't able to identify nor address. From kong controller logs (kubectl logs -n kong -f <kong_controller_pod_name>
):
[...]
2023-11-22T15:09:42Z error Failed parsing resource errors {"url": "https://10.244.0.125:8444", "update_strategy": "InMemory", "error": "could not unmarshal config error: json: cannot unmarshal object into Go struct field ConfigError.flattened_errors of type []sendconfig.FlatEntityError"}
2023-11-22T15:09:42Z error dataplane-synchronizer Could not update kong admin {"error": "performing update for https://10.244.0.125:8444 failed: failed posting new config to /config: got status code 400"}
This error was being thrown every 3 seconds.
Kong Ingress Controller running on minikube:
minikube start --driver=docker
minikube tunnel # running in another terminal
Then follow the steps from Get Started: Install KIC
File secrets.yaml
:
# JWT Credential for Admin
apiVersion: v1
kind: Secret
metadata:
name: jwt-admin-secret
labels:
konghq.com/credential: jwt
type: Opaque
stringData:
key: admin-issuer
algorithm: RS256
secret: empty # dummy field with arbitrary value, otherwise it throws an error
rsa_public_key: |
-----BEGIN PUBLIC KEY-----
[...]
-----END PUBLIC KEY-----
---
# JWT Credential for User
apiVersion: v1
kind: Secret
metadata:
name: jwt-user-secret
labels:
konghq.com/credential: jwt
type: Opaque
stringData:
key: user-issuer
algorithm: RS256
secret: empty # dummy field with arbitrary value, otherwise it throws an error
rsa_public_key: |
-----BEGIN PUBLIC KEY-----
[...]
-----END PUBLIC KEY-----
---
# Basic auth for a generic user
apiVersion: v1
kind: Secret
metadata:
name: user-generic-secret
labels:
konghq.com/credential: basic-auth
type: Opaque
stringData:
username: user
password: password
---
# Key auth for a generic API key
apiVersion: v1
kind: Secret
metadata:
name: key-generic-secret
labels:
konghq.com/credential: key-auth
type: Opaque
stringData:
key: key
File consumers.yaml
:
# Consumer for Admin JWT token
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
name: admin
annotations:
kubernetes.io/ingress.class: kong
username: admin
credentials:
- jwt-admin-secret # references Kubernetes secret
---
# Consumer for User JWT token
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
name: user
annotations:
kubernetes.io/ingress.class: kong
username: user
credentials:
- jwt-user-secret # references Kubernetes secret
---
# Consumer for generic basic auth user
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
name: generic-basic-auth-consumer
annotations:
kubernetes.io/ingress.class: kong
username: user
credentials:
- user-generic-secret # references Kubernetes secret
---
# Consumer for generic key auth
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
name: user-api-key-consumer
annotations:
kubernetes.io/ingress.class: kong
username: user-key-auth
credentials:
- key-generic-secret # references Kubernetes secret
---
# Consumer for anonymous user
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
name: anonymous-consumer
annotations:
kubernetes.io/ingress.class: kong
konghq.com/plugins: 'request-termination-anonymous'
username: anonymous
File plugins.yaml
:
# JWT authentication
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: jwt-auth-foobar
plugin: jwt
config:
anonymous: anonymous # references a Consumer username
---
# Basic authentication
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: basic-auth-foobar
plugin: basic-auth
config:
anonymous: anonymous # references a Consumer username
hide_credentials: true
---
# Key authentication
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: key-auth-foobar
plugin: key-auth
config:
key_names:
- apikey
anonymous: anonymous # references a Consumer username
hide_credentials: true
---
# Request termination: when the authentication fails
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: request-termination-anonymous
plugin: request-termination
config:
message: "Authentication required"
status_code: 401
File services.yaml
:
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: foobar
name: foobar
spec:
replicas: 1
selector:
matchLabels:
app: foobar
strategy: {}
template:
metadata:
labels:
app: foobar
spec:
containers:
- image: mikyll/foobar:latest
name: foobar
ports:
- containerPort: 3000
---
# Service
apiVersion: v1
kind: Service
metadata:
labels:
app: foobar-service
name: foobar-service
spec:
ports:
- port: 3000
name: http
protocol: TCP
targetPort: 3000
selector:
app: foobar
---
# Route /foobar/test/auth/key
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: foobar-route-test-keyauth
annotations:
konghq.com/strip-path: 'true'
konghq.com/plugins: 'key-auth-foobar'
spec:
parentRefs:
- name: kong
rules:
- matches:
- path:
type: PathPrefix
value: /foobar/test/auth/key
backendRefs:
- name: foobar-service
kind: Service
port: 3000
---
# Route /foobar/test/auth/basic
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: foobar-route-test-basicauth
annotations:
konghq.com/strip-path: 'true'
konghq.com/plugins: 'basic-auth-foobar'
spec:
parentRefs:
- name: kong
rules:
- matches:
- path:
type: PathPrefix
value: /foobar/test/auth/basic
backendRefs:
- name: foobar-service
kind: Service
port: 3000
---
# Route /foobar/test/auth/jwt
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: foobar-route-test-jwtauth
annotations:
konghq.com/strip-path: 'true'
konghq.com/plugins: 'jwt-auth-foobar'
spec:
parentRefs:
- name: kong
rules:
- matches:
- path:
type: PathPrefix
value: /foobar/test/auth/jwt
backendRefs:
- name: foobar-service
kind: Service
port: 3000
Applied with:
cat secrets.yaml | kubectl apply -f -
cat consumers.yaml | kubectl apply -f -
cat plugins.yaml | kubectl apply -f -
cat services.yaml | kubectl apply -f -
The issue was caused by these two consumers:
# Consumer for User JWT token
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
name: user
annotations:
kubernetes.io/ingress.class: kong
username: user # <-- HERE
credentials:
- jwt-user-secret
---
# Consumer for generic basic auth user
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
name: generic-basic-auth-consumer
annotations:
kubernetes.io/ingress.class: kong
username: user # <-- HERE
credentials:
- user-generic-secret
The configuration failed because both had the same username "user", and appearently that's not allowed. Therefore, changing one of them solved the issue.
New file consumers.yaml
:
# Consumer for Admin JWT token
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
name: admin
annotations:
kubernetes.io/ingress.class: kong
username: admin
credentials:
- jwt-admin-secret # references Kubernetes secret
---
# Consumer for User JWT token
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
name: user
annotations:
kubernetes.io/ingress.class: kong
username: user
credentials:
- jwt-user-secret # references Kubernetes secret
---
# Consumer for generic basic auth user
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
name: generic-basic-auth-consumer
annotations:
kubernetes.io/ingress.class: kong
username: generic
credentials:
- user-generic-secret # references Kubernetes secret
---
# Consumer for generic key auth
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
name: user-api-key-consumer
annotations:
kubernetes.io/ingress.class: kong
username: user-key-auth
credentials:
- key-generic-secret # references Kubernetes secret
---
# Consumer for anonymous user
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
name: anonymous-consumer
annotations:
kubernetes.io/ingress.class: kong
konghq.com/plugins: 'request-termination-anonymous'
username: anonymous
This problem occurs only in DB-less mode, and was added to KIC v3.1.x milestone.