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
MeshIdentity
to work you need to havemeshServices.mode: Exclusive
set 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.