This is a great example of why zero-trust is more about enforcing trust boundaries than adding authentication everywhere.
One pattern I've seen work well is keeping services completely unaware of JWTs and identity providers. Let the gateway authenticate, let the service mesh validate and project identity, and let the application focus purely on business logic. That separation makes services easier to test, swap, and secure without duplicating auth logic across every microservice.
The database identity propagation and RLS integration were especially interesting they close the loop so identity isn't lost after the request reaches the backend.
This was a core requirement when I designed it. The inspiration came from migrating older services that had auth baked in, which made them tightly coupled to the existing infra. With this approach, a service can be upgraded or replaced without other components changing and without the auth flow changing. The one downside is the per-service header projection: each service needs its own EnvoyFilter to strip inbound identity headers and a RequestAuthentication to project the verified claim into a service-specific header (x-ms2-user, x-ms3-user, and so on). Its a tradeoff easier migration, security and isolation for a costlier bill :)
This is a great example of why zero-trust is more about enforcing trust boundaries than adding authentication everywhere.
One pattern I've seen work well is keeping services completely unaware of JWTs and identity providers. Let the gateway authenticate, let the service mesh validate and project identity, and let the application focus purely on business logic. That separation makes services easier to test, swap, and secure without duplicating auth logic across every microservice.
The database identity propagation and RLS integration were especially interesting they close the loop so identity isn't lost after the request reaches the backend.