Episode 11 secures communication inside the mesh: automatic mTLS with PeerAuthentication and DestinationRule, JWT validation with RequestAuthentication, AuthorizationPolicy for access control, and certificate management with SDS.

Traffic can now be managed and observed. Time to secure it. Episode 11 covers the pillars of Istio security: mTLS for encryption and authentication between services, JWT validation to prove who the caller is, and AuthorizationPolicy to decide what is allowed.
The philosophy at the core: mesh security is based on workload identity, not just IP addresses. Because identity is guaranteed by istiod and embedded into certificates, policies can follow the workload wherever it runs.
Mutual TLS makes both sides verify each other's certificates. Istio automates this through PeerAuthentication:
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default
namespace: default
spec:
mtls:
mode: STRICTThe three available modes:
mtls.mode: STRICT guarantees there is no plaintext communication in that namespace. Use STRICT when every workload in the namespace is ready, and PERMISSIVE during the migration period.
As a legacy form, mTLS can also be triggered from a DestinationRule:
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: default
namespace: default
spec:
host: "*.local"
trafficPolicy:
tls:
mode: ISTIO_MUTUALtls.mode: ISTIO_MUTUAL tells the client to use the Istio certificate when contacting a matching host. In modern versions, PeerAuthentication is the recommended way; this kind of DestinationRule is only for compatibility or specific cases.
RequestAuthentication validates JWT tokens on requests. A valid token binds the user identity to the request:
apiVersion: security.istio.io/v1
kind: RequestAuthentication
metadata:
name: jwt-gateway
namespace: default
spec:
selector:
matchLabels:
app: productpage
jwtRules:
- issuer: "https://accounts.example.com"
jwksUri: "https://accounts.example.com/.well-known/jwks.json"
forwardOriginalToken: trueissuer and jwksUri tell Envoy where to get the public keys for verifying the JWT signature. Once active, a valid token adds claims to the request — for example request.auth.claims — which can be used in AuthorizationPolicy. Note that RequestAuthentication only validates; it does not reject requests without a token. Rejection is done by AuthorizationPolicy.
AuthorizationPolicy decides whether a request is allowed. The default rule: when a matching policy exists, everything is denied unless explicitly allowed:
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: productpage-reader
namespace: default
spec:
selector:
matchLabels:
app: productpage
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/frontend"]
to:
- operation:
methods: ["GET"]This policy lets the frontend service account call GET on productpage. Once applied, all other requests to productpage — including from other services — are rejected with 403. action can be ALLOW, DENY, or CUSTOM.
Finer control through when:
spec:
selector:
matchLabels:
app: productpage
action: ALLOW
rules:
- when:
- key: request.auth.claims[role]
values: ["admin"]
to:
- operation:
methods: ["POST"]when with request.auth.claims[role] only allows users with the role: admin claim. This is an example of using the JWT claims validated by RequestAuthentication.
Test rejection and allowance directly:
curl -s -o /dev/null -w "%{http_code}" http://productpage:9080/productpage
curl -H "Authorization: Bearer $TOKEN" http://productpage:9080/productpageCheck with and without a token to confirm that 403 and 200 responses appear according to the policy.
Istio issues workload certificates automatically. Certificates are delivered to Envoy via SDS (Secret Discovery Service) and rotated before they expire without a restart. Granular configuration can be set in MeshConfig:
spec:
meshConfig:
trustDomain: cluster.local
defaultConfig:
proxyMetadata:
ISTIO_META_DNS_CAPTURE: "true"trustDomain determines the root of identity — this value must be consistent across the entire mesh. For external CA integration such as cert-manager, add certificates in MeshConfig or use the Istio Certificate CRD with type: ISTIOD.
Warning
Changing the CA or trust domain requires planning: every workload must accept the new certificate before the old one expires. Do it gradually and always test in staging.
Episode 11 locked down communication inside the mesh: PeerAuthentication for automatic mTLS, RequestAuthentication for JWT validation, AuthorizationPolicy for identity-based access control, and certificate management via SDS with external CA integration options.
Key takeaways:
when enables JWT claim-based and other conditions.trustDomain must be consistent across the entire mesh.In the next episode, episode 12, we will manage isolation: multi-tenancy, namespace isolation, and RBAC — separating tenants with namespaces, limiting egress scope with the Sidecar CRD, and understanding the relationship between Kubernetes RBAC and Istio AuthorizationPolicy.