Linkerd automatically injects TLS encryption between your services, even if your application code knows nothing about TLS.

Let’s watch it in action.

Here’s a simple curl request from the webapp pod to the api pod:

kubectl exec -n demo deploy/webapp -- curl -s http://api.demo.svc.cluster.local:8080/

Without Linkerd, this is plain HTTP. With Linkerd installed and the demo namespace injected, it’s automatically upgraded to TLS. Linkerd’s proxy, running alongside your application container, handles the TLS handshake and encryption. The webapp pod thinks it’s talking HTTP to api.demo.svc.cluster.local:8080, but Linkerd is actually terminating the TLS from the webapp proxy and initiating a new TLS connection to the api proxy.

The magic is in the "Service Mirroring" and "SPIFFE" identity. When Linkerd sees traffic destined for a service in an injected namespace, its control plane has already issued a TLS certificate for the destination pod’s identity. This identity is based on the SPIFFE (Secure Production Identity Framework for Everyone) standard, which provides a globally unique identifier for workloads. For a pod named api-abcdef-12345 in the demo namespace, its SPIFFE ID might look like spiffe://mycluster.linkerd.cloud/ns/demo/sa/api.

When the webapp proxy receives the outgoing request, it checks its local trust bundle for a CA that can validate the destination’s SPIFFE ID. If it finds one (which it will, because the Linkerd control plane distributes the root CA to all proxies), it initiates a TLS handshake. The api proxy, receiving the connection, presents its own SPIFFE-based certificate. The webapp proxy verifies this certificate against the shared root CA. If successful, the connection is established with mutual TLS. The entire process is transparent to your application; it just sees a TCP connection.

Linkerd manages the lifecycle of these certificates. The control plane acts as a Certificate Authority (CA), signing certificates for each pod. These certificates have a short expiry (typically 24 hours), and the proxies automatically rotate them before they expire. This short-lived certificate model is a key security feature, limiting the blast radius if a private key were ever compromised.

The problem Linkerd solves here is the operational burden and complexity of implementing TLS for inter-service communication in a microservices environment. Manually provisioning, distributing, rotating, and validating certificates for hundreds or thousands of services is a nightmare. Linkerd automates this entirely. It also provides a consistent security posture across all services, regardless of their language or framework. You get mTLS without changing your application code.

A crucial, often misunderstood, aspect is how Linkerd enforces TLS. It doesn’t just encrypt; it requires TLS for communication between meshed pods. If a pod tries to connect to another meshed pod without TLS, the connection will be dropped by the destination pod’s proxy. This is configured via the policy.linkerd.io Custom Resource Definitions (CRDs). For instance, a NetworkPolicy resource can specify which pods are allowed to communicate with others. If a policy is in place allowing communication between webapp and api, and the webapp proxy attempts to connect to api without mTLS, the api proxy will reject the connection because it doesn’t meet the TLS requirement.

The next hurdle you’ll likely encounter is understanding how to configure fine-grained access control using Linkerd’s NetworkPolicy resources to restrict which services can talk to each other.

Want structured learning?

Take the full Linkerd course →