ICA study materials
ICA study resources

Strict mTLS Blocks a Legacy Billing Client

ICA · Put your knowledge to work in context.

All case studies

Strict mTLS Blocks a Legacy Billing Client

The payments namespace enforces PeerAuthentication STRICT and has a default-deny AuthorizationPolicy. All in-mesh callers use SPIFFE identities. A legacy billing service on a VM outside the mesh calls payments over plaintext HTTP on port 8080 and now receives connection resets. A separate Kubernetes reporting Job in the analytics namespace has sidecar injection disabled and also calls payments. Compliance requires that pod-to-pod traffic inside payments remain STRICT mTLS and that only billing and reporting may call the charge endpoint. You add a RequestAuthentication for the billing JWT issuer and an AuthorizationPolicy that requires request.auth.claims[iss] to equal the billing issuer on /charge. After this, billing still fails and reporting, which has no JWT, is also denied. You must restore both callers without weakening intra-mesh STRICT mTLS or allowing any other namespace to call /charge.

1. Explain why billing still fails and why reporting is denied after adding the JWT policy. What is the correct way to admit a non-mesh VM and a non-injected pod while keeping STRICT mTLS for mesh workloads?

Read the worked answer

Billing fails because STRICT PeerAuthentication requires a valid mTLS identity from a sidecar. A VM outside the mesh has no Istio sidecar and no SPIFFE certificate, so the payments sidecar resets the plaintext connection before HTTP or JWT processing occurs. The RequestAuthentication policy cannot help because the connection never reaches the HTTP filter chain.

Reporting is denied because RequestAuthentication validates a JWT only when one is present; it is not an authentication gate by itself. The AuthorizationPolicy requires request.auth.claims[iss], and a request with no token has no claims. Missing claims do not match the rule, so reporting is denied under default-deny.

Admission options that preserve STRICT for mesh workloads:

  • Onboard the VM into the mesh with a sidecar and a WorkloadEntry, so billing presents a mesh identity and can use mTLS.
  • Or place an ingress/east-west gateway in front of payments. The gateway accepts plaintext from the legacy VM, authenticates it, and originates mTLS to payments. Payments still sees only mTLS from a known gateway principal.
  • For reporting, inject a sidecar or route it through the same gateway. Do not set a port-level DISABLE on the payments workload just to admit one legacy caller.

Then enforce authorization on the gateway or payments identity, not on the VM IP address.

2. Design the authorization model at a conceptual level: which resources, match conditions, and principals. Explain why an ALLOW policy with a JWT condition does not automatically allow tokenless requests and how to separate billing from reporting.

Read the worked answer

Keep default-deny in payments. Add RequestAuthentication on the workload or gateway that receives the JWT, with the billing issuer and JWKS. Add an ALLOW AuthorizationPolicy for the charge path with separate rules:

  • Billing rule: match POST /charge, allow the gateway or VM workload principal, and require request.auth.claims[iss] plus a subject or audience claim that identifies billing. Do not rely on source.ip for the VM; use the authenticated principal.
  • Reporting rule: match POST /charge, allow the reporting service account principal or the gateway principal with a separate claim or header that identifies reporting. If reporting has no JWT, do not put it in a rule that requires a claim.

An ALLOW policy with a JWT condition does not allow tokenless requests because the condition is part of the rule match. If the claim is absent, the rule does not match, and with default-deny the request is rejected. RequestAuthentication only validates tokens; AuthorizationPolicy enforces access.

To separate callers, avoid one broad rule that says from source.namespaces: [payments, analytics] and when claims[iss]. Instead, use two rules with distinct principals and distinct conditions. If both callers come through the same gateway, have the gateway add a trusted header or use separate gateway workloads with different identities. Test with istioctl x authz check and negative tests: a tokenless request, a token from the wrong issuer, and a valid token from the wrong subject should all be denied.