Istio Peer connection clarification


i’m trying to understand when communication between microservices pass through the Envoy and when it isnt. i assumed once sidecar injected all communication between service A to service B is basically:
serviceA --> SideCarA --> SideCarB --> Service B.

i’ve started to doubt it due to the following scenario:
i have two services, A and B which includes the following endpoints:

  • service A includes /headers endpoint that just print request headers
  • service B includes /headers endpoint that just print request headers
    and also / endpoint that reach to serviceA/headers endpoint and print the response headers.

now, from an helper pod (sleep) i’m doing the following:

  • curl http://serviceb:8080/headers i get response and also see the X-Forwaarded-Client-Cert which indicate the communication here is mTLs and through envoys.
  • curl http://servicea:8080/headers same thing. got mTLs through envoys
  • curl http://serviceb:8080/ prints the headers and does not includes the X-Forwarded-Client-Cert.
    why? i’m not sure i understand why flow from B to A isnt also through Envoys.

why i’m trying to understand this usecase?
cause once i’m applying the following:

kind: AuthorizationPolicy
  name: jwt-required
  namespace: default
  - from:
    - source:
        requestPrincipals: ["*"]
    - source:
        namespaces:  ["default"]

i expected to be able to use curl with valid JWT token (using requestauth) but also to be able to allow services communicates with each other.
i do able to do the curl thing, but once code includes http to other service i get the rbac.
why it is different? and sorry if its pretty basic question



For the observation of ‘curl’ with unexpected missing X-Forwarded-Client-Cert, one thing you could check is the configuration of PeerAuthentication see if the mTLS is enabled among these pods.
And you could also try curl from the A to B see if the header is injected or not.
You can also find the behavior of the header injection here:

For the question about the AuthorizationPolicy, you could find details in
And from your config, the policy is specifying the namespaces, the expectation would be fail if you curl from outside, not sure if that is the case.

i’m familiar with the documentation and indeed checked this part.
the problem was so silly, the code from serviceA to serviceB included overwrite of headers, this caused the flow not to work properly.
once i’ve removed it , everything got working again.