mTLS
Create a Secret containing a CA Certificate and pass the ID of the certificate to an mTLS plugin configuration.
Prerequisites
Kong Konnect
If you don’t have a Konnect account, you can get started quickly with our onboarding wizard.
- The following Konnect items are required to complete this tutorial:
- Personal access token (PAT): Create a new personal access token by opening the Konnect PAT page and selecting Generate Token.
-
Set the personal access token as an environment variable:
export KONNECT_TOKEN='YOUR KONNECT TOKEN'
Copied to clipboard!
About mTLS
Mutual TLS (mTLS) is a way to secure connectivity using certificates. Kong Gateway can look for a certificate in incoming requests and reject the request if the public key presented does not match the private key stored in Kong Gateway.
Generate a CA certificate
To use the mtls-auth
plugin you need a CA certificate. If you don’t have one, generate a new certificate using openssl
:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes \
-subj "/C=US/ST=California/L=San Francisco/O=Kong/OU=Org/CN=www.example.com"
Add the Certificate to Kong Gateway
CA Certificates in Kong Gateway are provisioned by creating a Secret
or ConfigMap
resource in Kubernetes.
Resources holding CA certificates must have the following properties:
- The
konghq.com/ca-cert: "true"
label applied - A
cert
orca.crt
data property which contains a valid CA certificate in PEM format - A
kubernetes.io/ingress.class
annotation whose value matches the value of the controller’s--ingress-class
argument. By default, that value iskong
. - An
id
data property which contains a random UUID
Each CA Certificate that you create needs a unique ID. Any random UUID should suffice here, and it doesn’t have a security implication. You can use uuidgen (Linux, macOS) or New-Guid (Windows) to generate an ID.
CERT_ID=$(uuidgen | tr "[:upper:]" "[:lower:]")
kubectl create secret -n kong generic my-ca-cert --from-literal=id=$CERT_ID --from-file=cert=./cert.pem
kubectl label secret -n kong my-ca-cert 'konghq.com/ca-cert=true'
kubectl annotate secret -n kong my-ca-cert 'kubernetes.io/ingress.class=kong'
Configure the mtls-auth plugin
The mtls-auth plugin requires a CA Certificate ID that will be used to validate the Certificate in the incoming request. In this example we disable revocation checks, but you should enable checks in a production setting.
echo "
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
name: mtls-auth
namespace: kong
annotations:
kubernetes.io/ingress.class: kong
config:
ca_certificates:
- '$CERT_ID'
skip_consumer_lookup: true
revocation_check_mode: SKIP
plugin: mtls-auth
" | kubectl apply -f -
Next, apply the KongPlugin
resource by annotating the service
resource:
kubectl annotate -n kong service echo konghq.com/plugins=mtls-auth
Validate your configuration
At this point, Kong Gateway will reject requests that do not contain a client certificate.
-
Send a request to check Kong Gateway prompts for a client certificate:
curl "$PROXY_IP/echo"
Copied to clipboard!You should see the following response:
No required TLS certificate was sent
Copied to clipboard!curl "$PROXY_IP/echo"
Copied to clipboard!You should see the following response:
No required TLS certificate was sent
Copied to clipboard!As you can see, Kong Gateway is restricting the request because it doesn’t have the necessary authentication information.
Two things to note here:
-
-k
is used because Kong Gateway is set up to serve a self-signed certificate by default. For full mutual authentication in production use cases, you must configure Kong Gateway to serve a Certificate that is signed by a trusted CA. - For some deployments
$PROXY_IP
might contain a port that points tohttp
port of Kong Gateway. In others, it might contain a DNS name instead of an IP address. If needed, update the command to send anhttps
request to thehttps
port of Kong Gateway or the load balancer in front of it.
-
-
Use the key and Certificate to authenticate against Kong Gateway and use the Service:
curl -k --key key.pem --cert cert.pem "https://$PROXY_IP/echo"
Copied to clipboard!curl -k --key key.pem --cert cert.pem "https://$PROXY_IP/echo"
Copied to clipboard!The results should look like this:
HTTP/2 200 content-type: text/plain; charset=UTF-8 server: echoserver x-kong-upstream-latency: 1 x-kong-proxy-latency: 1 via: kong/x.y.z
Copied to clipboard!
Cleanup
Delete created Kubernetes resources
kubectl delete -n kong -f https://developer.konghq.com/manifests/kic/echo-service.yaml