This is a guide for experimental feature.
The MeshIdentity allows you to manage identity for selected data planes. In this guide we will take a look on how to issue identities using Spire provider and how to use them encrypt traffic in mesh.
This is a guide for experimental feature.
The MeshIdentity allows you to manage identity for selected data planes. In this guide we will take a look on how to issue identities using Spire provider and how to use them encrypt traffic in mesh.
Before you begin, make sure you have the following tools installed:
Start a local Kubernetes cluster using minikube. The -p flag creates a new profile named mesh-zone:
minikube start -p mesh-zone
If you already have a running Kubernetes cluster, either locally or in the cloud (for example, EKS, GKE, or AKS), you can skip this step.
Install Kong Mesh control plane with Helm by executing:
helm repo add kong-mesh https://kong.github.io/kong-mesh-charts
helm repo update
helm install --create-namespace --namespace kong-mesh-system \
--set "kuma.controlPlane.envVars.KUMA_RUNTIME_KUBERNETES_INJECTOR_SPIRE_ENABLED=true" \
kong-mesh kong-mesh/kong-mesh
We need to enable Kubernetes Spire injector on control plane for Spire support to work.
Install Spire CRDs:
helm upgrade --install --create-namespace -n spire spire-crds spire-crds \
--repo https://spiffe.github.io/helm-charts-hardened/
Install Spire with custom trust domain default.local-zone.mesh.local. We will use this trust domain in next steps to configure
MeshIdentity
helm upgrade --install -n spire spire spire \
--repo https://spiffe.github.io/helm-charts-hardened/ \
--set "global.spire.trustDomain=default.local-zone.mesh.local" \
--set "global.spire.tools.kubectl.tag=v1.31.11"
We need to configure Spire to issue identities in kuma-demo namespace.
echo "apiVersion: spire.spiffe.io/v1alpha1
kind: ClusterSPIFFEID
metadata:
name: spire-registration
spec:
podSelector:
matchLabels:
kuma.io/mesh: default
spiffeIDTemplate: 'spiffe://{{ .TrustDomain }}/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }}'
workloadSelectorTemplates:
- 'k8s:ns:kuma-demo'" | kubectl apply -f -
We specify SpiffeID template that will use our configured trust domain, namespace and service account name.
kubectl apply -f https://raw.githubusercontent.com/kumahq/kuma-counter-demo/refs/heads/main/k8s/000-with-kuma.yaml
kubectl wait -n kuma-demo --for=condition=ready pod --selector=app=demo-app --timeout=90s
For the
MeshIdentityto work you need to havemeshServices.mode: Exclusiveset on Mesh resource. It is already configured in demo.
Port-forward the service to the namespace on port 5000:
kubectl port-forward svc/demo-app -n kuma-demo 5050:5050
Try making requests to demo-app
curl -XPOST localhost:5050/api/counter
You should see similar results:
{"counter":1,"zone":""}
In Kong Mesh we define two concepts around identity that need to be well understood:
In Kong Mesh we have MeshIdentity resource responsible for managing identity. In our scenario Spire is responsible for
issuing identity and managing trust, but we still need to create MeshIdentity to configure data plane to use identity
managed by Spire.
echo "apiVersion: kuma.io/v1alpha1
kind: MeshIdentity
metadata:
name: identity-spire
namespace: kuma-system
labels:
kuma.io/mesh: default
kuma.io/origin: zone
spec:
selector:
dataplane:
matchLabels: {}
spiffeID:
trustDomain: default.local-zone.mesh.local
path: '/ns/{{ .Namespace }}/sa/{{ .ServiceAccount }}'
provider:
type: Spire
spire: {}" | kubectl apply -f -
Let’s take a closer look at resource we’ve just applied. MeshIdentity uses selector field to select data planes for
which identity should be issued. In our example, identity will be issued for all data planes in Mesh.
Next is spiffeID field. This field contains templates for building spiffeID for our workloads. In this example we
need to use the same trust domain that we configured in Spire: default.local-zone.mesh.local with path that will be
dynamically created from namespace and service account name.
Example spiffeID will look like this spiffe://default.local-zone.mesh.local/ns/kuma-demo/sa/default.
Last thing we see in this example is provider field. This field contains configuration specific to identity provider.
We just need to specify Spire as a provider type.
In the GUI when you open Mesh view, you will see new sections with MeshIdentity and MeshTrust, where you can inspect these resources.
We can now make some requests to our demo-app:
curl -XPOST localhost:5050/api/counter
We should see errors like this:
{"instance":"d11ee97a4b45ff3a7b59091d1612b7f7","status":500,"title":"failed to retrieve zone","type":"https://github.com/kumahq/kuma-counter-demo/blob/main/ERRORS.md#INTERNAL-ERROR"}
Since we issued identity for our workloads, mTLS was also configured. Zero trust is default behavior in this situation, and because
we don’t have any MeshTrafficPermission configured we see these errors.
To allow traffic in kuma-demo we need to create MeshTrafficPermission. Apply this:
echo "apiVersion: kuma.io/v1alpha1
kind: MeshTrafficPermission
metadata:
name: mtp
namespace: kuma-demo
labels:
kuma.io/mesh: default
spec:
rules:
- default:
allow:
- spiffeID:
type: Prefix
value: spiffe://default.local-zone.mesh.local/ns/kuma-demo" | kubectl apply -f -
This MeshTrafficPermission uses rules API with spiffeID matching. This policy will allow all traffic from workloads which spiffeID starts with:
spiffe://default.local-zone.mesh.local/ns/kuma-demo. This spiffeID is based on template from MeshIdentity we’ve created earlier, every workload in default Mesh.
and in kuma-demo namespace will have spiffeID with this prefix. In the future if you want to be more specific you can
allow only workloads matching its exact spiffeID.
We can now try if traffic works. Run:
curl -XPOST localhost:5050/api/counter
You should see something similar to:
{"counter":3,"zone":""}
We’ve learned how to issue identity with Spire and MeshIdentity. Also, we’ve seen how to allow traffic using MeshTrafficPermission with spiffeID matchers.