ICA — Istio Certified Associate
Read allow paths and deny conditions together
In one line
Obtaining authentication information and allowing only when that information is satisfied are different tasks. By comparing four payment services with real Istio sidecars, this lab investigates the incident in which attaching one more policy actually increases the requests that can get through.
Why this was needed
Suppose a team made only the orders service able to call the payment API. A security review raised the requirement that a user JWT is also needed. The team left the existing workload allow policy in place and added a policy that allows requests with a JWT principal. They even named the file require-jwt. In the review, they thought that since both policies had been read, there were now two conditions.
But orders requests without a token kept passing. More surprising, even a stranger with a valid token passed. A file name is not its execution meaning. What the server evaluates is the combination of policies. In a situation where it opens if either the existing allow or the new allow is satisfied, adding a policy can be making one more door.
This is not simply a matter of changing one word in YAML. You must check to which condition each of the request's source, user token, method, path, and port is tied. Sending a single successful request will not reveal this incident. You must put the conditions under which a legitimate user succeeds and the conditions under which an unfamiliar user fails in the same table.
How it works
In the ica-policy namespace of the lab VM, there are two clients, orders and stranger. They use different service accounts. baseline, union, intersection, and scoped are four servers that give the same response, but policies can be attached to each independently. The lab does not connect to an external IdP and uses an RSA key generated on the VM and a synthetic JWT. Do not bring in real user tokens or production keys.
| Comparison target | Question to investigate |
|---|---|
| baseline | What happens to orders without a token if there is only a workload allow? |
| union | If you add a JWT allow separately, do the stranger and other paths open too? |
| intersection | What changes if you put two kinds of identity in the same source? |
| scoped | How are other ports preserved while applying a no-JWT DENY? |
principals is the workload identity confirmed by mTLS, and requestPrincipals is the request principal from a verified JWT. The two values are not different names for the same person. They handle, respectively, the source of the server-to-server connection and the claim of the user carried over that connection. You can require fields in the same source together, but splitting a from item into two changes the meaning. Picture in a diagram the combination inside one item versus the selection among the list.
For ALLOW policies among themselves, you look at whether a path remains where any one of them matches. When using DENY, design it so that the deny conditions are checked first and the existing least-privilege allow works for requests that are not denied. The scoped in this lab denies only requests on 8080 that have no token. It does not claim to protect even 8081 and is left as a comparison case that actually allows orders' token-less 8081 requests.
Port scope is not a side decoration. When designing a DENY that uses HTTP-only attributes, you must also think about its effect on other protocols and ports. Here only two HTTP ports are measured. Do not broaden the claim to say the lab results verified all of TCP or even an ambient mesh.
What it looks like in the field
When reviewing a policy change request, first write the requirement in a short sentence. For example, "Allow only requests that come from orders, with a verified payment JWT, and reach POST /v1/charges." Then check whether the conditions separated by commas are tied into one rule and whether another allow policy bypasses those conditions. Finally, send requests in which you change the words of this sentence one at a time. If the result is the same even when you change the source to stranger, the token to none, and the path to /admin/test, the requirement may not have been implemented sufficiently.
Collecting only 403s does not pin down the cause. In this pinned-version measurement, a token with a different audience also gave a 403, but the body was a JWT audience rejection, and an authorization denial for a workload identity or path was an RBAC denial. Conversely, an expired token, a different issuer, and a malformed token were 401. You must record the response code, the body, and the applied policy together so that the next person does not confuse JWT verification with authorization.
A policy being stored successfully does not mean it has been reflected in the data plane. Grading in this lab also checks whether the same set of requests matches twice in a row. If it failed right after you applied, first look at the current response with an observation command, and grade again after propagation has converged. Widening the conditions to make the failure go away is not recovery.
What you will do in the next lab
First you record the current UIDs of six Pods. Next you compare the baseline and the deliberately wrong union, and configure intersection and scoped correctly. The initial audience list of intersection is set wide so that it allows both the payment API and other APIs, so narrow it to just the payment one. At the end you leave the port-boundary measurements and an incident report.
The four comparison targets stay together to the end. So the overall grading does not trust the historical success markers of earlier steps and checks the current state again. However, union is an isolated target that is deliberately left wide open to reproduce the incident. Do not carry this configuration over to a production environment. When the VM is terminated, the synthetic key and the working files are reclaimed along with it.
Check further in the official documentation
- AuthorizationPolicy: policy combination, Source field combination, and the DENY port scope.
- RequestAuthentication: the meaning of issuer, audiences, and public key material.
- JWT authorization lab: the official example that verifies authentication and authorization separately.