Stage 5 · Platform
Networking & Service Mesh
Mesh mTLS & Identity
Istio, Linkerd, SPIFFE IDs, certificate rotation, and zero-trust service identity.
mTLS Identity Model
Service mesh mTLS creates a cryptographic identity for every service. When two services communicate, they present certificates that prove their identity. The mesh CA issues short-lived certificates (24h default) and rotates them automatically. This eliminates the need for shared secrets or API keys.
Service A -> Service B:
1. Service A connects to Service B
2. Service B presents its certificate (SPIFFE ID)
3. Service A validates the certificate against the mesh CA
4. Service A presents its own certificate
5. Service B validates Service A's certificate
6. Encrypted tunnel established with mutual authenticationThe entire handshake is transparent to the application. The proxy handles certificate presentation, validation, and encryption. The application sees a plain TCP connection.
SPIFFE Identity
SPIFFE (Secure Production Identity Framework for Everyone) provides a standard identity format for services. A SPIFFE ID is a URI: spiffe://trust-domain/workload-identifier. Kubernetes uses the cluster domain as the trust domain.
# Format: spiffe://<trust-domain>/<namespace>/<service-account>
# Examples:
spiffe://cluster.local/ns/production/sa/api-service
spiffe://cluster.local/ns/database/sa/postgres
spiffe://cluster.local/ns/monitoring/sa/prometheus
# Istio uses a slightly different format:
spiffe://cluster.local/ns/production/sa/api-serviceThe SPIFFE ID is embedded in the X.509 certificate's Subject Alternative Name (SAN) field. This provides a cryptographically verified identity that can be used for authorization decisions.
The trust domain identifies the cluster. In Istio, it defaults to cluster.local. For multi-cluster meshes, use a shared trust domain (e.g., corporate.example.com) to enable cross-cluster mTLS. All clusters sharing the trust domain trust each other's certificates.
Certificate Rotation
Certificate rotation is the process of issuing new certificates before old ones expire. The mesh CA issues short-lived certificates (24h) and proxies rotate them automatically. This limits the window of compromise — a stolen certificate is only valid for hours, not months.
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
meshConfig:
defaultConfig:
proxyMetadata:
# Certificate rotation interval
ISTIO_META_CERT_DURATION: "24h"
# How often to check for rotation
ISTIO_META_CERT_RENEW_INTERVAL: "12h"
# CA configuration
caAddress: istiod.istio-system.svc:15012
components:
pilot:
k8s:
env:
# Workload certificate TTL
- name: DEFAULT_WORKLOAD_CERT_TTL
value: "24h"
# Rotation check interval
- name: SECRET_TTL
value: "24h"Certificates are valid for 24h and checked for renewal every 12h. When 50% of the certificate lifetime has elapsed, the proxy requests a new certificate. The old certificate remains valid until the new one is issued.
Istio PKI
Istio's PKI (Public Key Infrastructure) consists of: the root CA (self-signed or external), the istiod CA (issues intermediate certificates), and the workload certificates (issued to proxies). The root CA signs the istiod certificate; istiod signs workload certificates.
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
profile: default
meshConfig:
defaultConfig:
proxyMetadata:
ISTIO_META_AUTO_RELOAD_MOUNTED_CERTS: "true"
values:
global:
pilotCertProvider: istiod
pilot:
env:
# Use external CA for root certificate
- name: EXTERNAL_CA
value: ISTIOD_RA_KUBERNETES_API
# Or use a custom CA
# - name: EXTERNAL_CA
# value: ISTIOD_RA_CERT_PROVIDED
components:
pilot:
k8s:
# Mount external CA certificate
volumes:
- name: external-ca-cert
secret:
secretName: external-ca-cert
optional: true
volumeMounts:
- name: external-ca-cert
mountPath: /etc/cacerts
readOnly: trueFor production, use an external CA (HashiCorp Vault, AWS Private CA) instead of istiod's self-signed CA. The external CA signs istiod's certificate, which in turn signs workload certificates.
Linkerd Identity
Linkerd uses a simpler PKI model: a trust anchor (root certificate) and an issuer certificate (signed by the trust anchor). The issuer signs workload certificates. Linkerd's identity component handles certificate issuance and rotation.
# Check Linkerd identity certificates
linkerd viz check --output json | jq '.categories[] | select(.name == "linkerd-identity")'
# View certificate details
kubectl get secret linkerd-identity -n linkerd -o yaml
# Rotate certificates
linkerd upgrade --identity-trust-anchors-file ca.crt \
--identity-issuer-certificate-file issuer.crt \
--identity-issuer-key-file issuer.keyLinkerd's trust anchor is a self-signed root CA. The issuer certificate is signed by the trust anchor and used to sign workload certificates. Rotate the issuer certificate periodically without changing the trust anchor.
Zero Trust Implementation
Zero trust means no implicit trust based on network location. Every request must be authenticated and authorized. Implement zero trust in Kubernetes: encrypt all traffic with mTLS, authenticate service identity, authorize based on identity, and audit all access.
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: production
spec:
mtls:
mode: STRICT
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: api-access
namespace: production
spec:
selector:
matchLabels:
app: api
rules:
- from:
- source:
principals:
- cluster.local/ns/production/sa/frontend
- cluster.local/ns/monitoring/sa/prometheus
to:
- operation:
methods: ["GET", "POST"]
paths: ["/api/*"]
when:
- key: request.auth.claims[iss]
values: ["https://accounts.example.com"]This policy enforces: mTLS for all traffic (STRICT mode), only frontend and prometheus can access the API, only GET/POST on /api/*, and requests must come from a valid JWT issuer. This is zero-trust in action.
Start with PERMISSIVE mode (accepts both plaintext and mTLS). Deploy mTLS for all services. Then switch to STRICT mode. Monitor with istioctl analyze and check for services still using plaintext.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.