ALL ARCHITECTURE

Architecture

Zero-Trust Mesh

istiod issues short-lived certificates; PeerAuthentication enforces STRICT on the server, DestinationRule sends mTLS from the client. A sidecar-less caller is refused — that's the feature.

scroll to render
01

What you're looking at

istiod is the mesh certificate authority. It issues a short-lived identity to each Envoy sidecar — those are the small wireframe cubes sitting above each service. Traffic between the two sidecars is mutual TLS: both ends present a certificate and both verify. The red client at the bottom has no sidecar, so it has no identity, and its plaintext connection is refused. The dashed red edge is that refusal.

02

PERMISSIVE is the trap

Istio defaults to PERMISSIVE, which accepts both mTLS and plaintext. Teams enable the mesh, see mTLS between sidecar-injected pods, and conclude they are encrypted. They are — for the pods that happen to have sidecars. Every legacy caller is still sending plaintext and nothing reports it as a problem, because PERMISSIVE is doing exactly what it says.

03

What goes wrong here

Flipping to STRICT severs every plaintext path at once, and the plaintext paths are the ones nobody has an inventory of. The symptom is connection reset by peer from services that were fine a minute ago. Migrate per-namespace, verify each one, and only then go mesh-wide.

Inspect it yourself

  • Which pods actually have a sidecar

    kubectl get pods -A -o json | jq -r '.items[] | select([.spec.containers[].name] | index("istio-proxy") | not) | "\(.metadata.namespace)/\(.metadata.name)"'

    Everything listed is a pod STRICT will cut off. This inventory is the migration plan.

  • Is this connection genuinely encrypted?

    istioctl x describe pod POD -n NS | grep -A3 'mTLS'

    Reports the effective policy for the pod rather than what the YAML intends — the two diverge more often than you would like.

  • Count plaintext connections still arriving

    kubectl exec POD -c istio-proxy -- pilot-agent request GET stats | grep -E 'ssl.handshake|ssl.no_certificate'

    A non-zero no_certificate counter means something is still connecting without an identity. Enforce STRICT when it reaches zero and stays there.

Read the source

Components

  • ISTIODcertificate authority
  • SERVICE-Aapp + envoy
  • ENVOY
  • SERVICE-Bapp + envoy
  • ENVOY
  • LEGACY CLIENTno sidecar

Flows

  • istiodenvacert
  • istiodenvbcert
  • envaenvbmTLS STRICT
  • legacysvcbRESET