Introduce zero-trust security with Kong Mesh

Uses: Kong Mesh
TL;DR

Enable mTLS with a built-in CA to encrypt all traffic, apply MeshTrafficPermission policies to control access, and configure a built-in gateway to route external traffic into the mesh.

Prerequisites

This page is part of the Get started with Kong Mesh on Universal series.

Complete the previous page, Set up a Kong Mesh demo application before completing this page.

By default, the network is insecure and unencrypted. With Kong Mesh, you can enable the Mutual TLS (mTLS) policy to secure the network. It sets up a Certificate Authority (CA) that automatically provides TLS certificates to your services, specifically to the data plane proxies running next to each service.

Enable Mutual TLS

Enable Mutual TLS using a builtin CA backend:

echo 'type: Mesh
name: default
meshServices:
  mode: Exclusive
mtls:
  enabledBackend: ca-1
  backends:
  - name: ca-1
    type: builtin' | kumactl apply -f -

After enabling mTLS, all traffic is encrypted and secure. However, you can no longer access the demo-app directly, meaning http://127.0.0.1:25050 will no longer work. This happens for two reasons:

  • Kong Mesh doesn’t create traffic permissions by default when mTLS is enabled. No traffic will flow until you define a MeshTrafficPermission policy.
  • Browsers and HTTP clients outside the mesh don’t have a valid certificate signed by the ca-1 CA, so their connections are rejected.

Allow traffic between demo-app and kv

Apply a MeshTrafficPermission policy to allow traffic between the kv and demo-app services:

echo 'type: MeshTrafficPermission 
name: allow-kv-from-demo-app
mesh: default 
spec: 
  targetRef:
    kind: Dataplane
    labels:
      app: kv
  from: 
  - targetRef: 
      kind: MeshSubset 
      tags:
        kuma.io/service: demo-app
    default: 
      action: Allow' | kumactl apply -f -

To allow external traffic into the mesh, we’ll use the built-in gateway that Kong Mesh provides.

Create a Dataplane resource

The built-in gateway needs its own Dataplane resource, separate from the service data plane proxies. Unlike the service Dataplane template used in previous steps, the gateway uses a static configuration since there’s only one instance:

echo 'type: Dataplane
mesh: default
name: edge-gateway-instance-1
networking:
  gateway:
    type: BUILTIN
    tags:
      kuma.io/service: edge-gateway
  address: 172.57.78.4' > "$KONG_MESH_DEMO_TMP/dataplane-edge-gateway.yaml"

Generate a data plane token

The gateway proxy requires a data plane token to securely register with the control plane. Generate the token using the following command:

kumactl generate dataplane-token \
  --tag kuma.io/service=edge-gateway \
  --valid-for 720h \
  > "$KONG_MESH_DEMO_TMP/token-edge-gateway"

Start the gateway container

With the configuration and token in place, we can start the gateway proxy as a container:

docker run \
  --detach \
  --name kong-mesh-demo-edge-gateway \
  --hostname gateway \
  --network kong-mesh-demo \
  --ip 172.18.78.4 \
  --publish 28080:8080 \
  --volume "$KONG_MESH_DEMO_TMP:/demo" \
  kong/kuma-dp:2.13.5 run \
    --cp-address https://control-plane:5678 \
    --dataplane-token-file /demo/token-edge-gateway \
    --dataplane-file /demo/dataplane-edge-gateway.yaml \
    --dns-enabled=false

This command starts the gateway proxy and registers it with the control plane. However, the gateway is not yet ready to route traffic.

Configure the gateway with MeshGateway

To enable the gateway to accept external traffic, configure it with a MeshGateway. This setup defines listeners that specify the port, protocol, and tags for incoming traffic, allowing policies like MeshHTTPRoute or MeshTCPRoute to route traffic to services:

echo 'type: MeshGateway
mesh: default
name: edge-gateway
selectors:
- match:
    kuma.io/service: edge-gateway
conf:
  listeners:
  - port: 8080
    protocol: HTTP
    tags:
      port: http-8080' | kumactl apply -f -

This sets up the gateway to listen on port 8080 using the HTTP protocol and adds the tag port: http-8080 to identify this listener in routing policies.

You can test the gateway by visiting http://127.0.0.1:28080. You should see a message saying no routes match this MeshGateway. This means the gateway is running, but no routes are set up yet to handle traffic.

Create a route to connect the gateway to demo-app

To route traffic from the gateway to the service, create a MeshHTTPRoute policy:

echo 'type: MeshHTTPRoute
name: edge-gateway-demo-app-route
mesh: default
spec:
  targetRef:
    kind: MeshGateway
    name: edge-gateway
    tags:
      port: http-8080
  to:
  - targetRef:
      kind: Mesh
    rules:
    - matches:
      - path:
          type: PathPrefix
          value: "/"
      default:
        backendRefs:
        - kind: MeshService
          name: demo-app' | kumactl apply -f -

This route connects the gateway and its listener to the demo-app service. It forwards any requests with the path prefix / to demo-app.

After setting up this route, the gateway will try to send traffic to demo-app. However, if you test it by visiting http://127.0.0.1:28080, you’ll see:

RBAC: access denied

This happens because there is no MeshTrafficPermission policy allowing traffic from the gateway to demo-app.

Allow traffic from the gateway to demo-app

To fix the RBAC: access denied error, create a MeshTrafficPermission policy to allow the gateway to send traffic to demo-app:

echo 'type: MeshTrafficPermission
name: allow-demo-app-from-edge-gateway
mesh: default
spec:
  targetRef:
    kind: Dataplane
    labels:
      app: demo-app
  from:
  - targetRef:
      kind: MeshSubset
      tags:
        kuma.io/service: edge-gateway
    default:
      action: Allow' | kumactl apply -f -

This policy allows traffic from the gateway to demo-app. After applying it, you can access http://127.0.0.1:28080, and the traffic will reach the demo-app service successfully.

Cleanup

Remove the Docker containers, network, temporary directory, and the control plane configuration from kumactl:

kumactl config control-planes remove --name kong-mesh-demo

docker rm --force \
   kong-mesh-demo-control-plane \
   kong-mesh-demo-kv \
   kong-mesh-demo-app \
   kong-mesh-demo-edge-gateway

docker network rm kong-mesh-demo

rm -rf /tmp/kong-mesh-demo

Help us make these docs great!

Kong Developer docs are open source. If you find these useful and want to make them better, contribute today!