Checkpoint: What Counts as Isolation?

The abstract post-filtering model and the PostgreSQL case now give us one concrete judgment to make: is an unauthorized row absent from the computation, or merely absent from the answer? This checkpoint connects the query path, the timing oracle, and the reconstruction strategy into a reusable isolation test. The value is not another summary of PostgreSQL; it is a way to recognize the same boundary problem when a different system exposes a different signal.

What the PostgreSQL case establishes

The most important distinction is between three states that can look identical to an authorized caller. A candidate query may match no row at all. It may match a row the caller is allowed to see. Or it may match a row that exists in the shared table but is removed by row-level security. The returned content tells the caller which authorized data crossed the boundary, but it need not reveal which of the other two states occurred.

The PostgreSQL mechanism gives those states different execution histories. When an indexed, LEAKPROOF predicate is pushed into an index scan, the database can evaluate it over the shared table before applying the RLS policy. A nonexistent predicate produces no intermediate match. A predicate that finds a private row produces a nonempty intermediate result, and the policy still has work to do before discarding it. If that additional work shifts client-observed time, an empty response can carry a membership fact.

This is a useful diagnosis because it identifies the trigger, mediator, and outcome separately. The trigger is the user-selected predicate and the optimizer's permission to evaluate it early. The mediator is the amount of data-dependent work, especially the policy evaluation over the intermediate result. The outcome is a timing difference that the caller can classify. The policy did not return the hidden row. The execution path nevertheless allowed the hidden row to influence an observable property.

A calibrated comparison is what turns this possibility into evidence. The researcher does not ask whether one request was slow in isolation. They establish reference behavior for a known-empty query and a known-one-row query, then compare repeated observations of a candidate query with the gap between those references. The purpose is to distinguish distributions, not to trust an arbitrary threshold. A practical deployment may add enough variance to make the distributions overlap; in that case the same mechanism may be difficult to exploit reliably. But difficulty of measurement is not the same as removal of the dependency.

The model also explains why a correct RLS policy is not the end of the analysis. The predicate can be correct as an authorization rule, and the optimizer can be correct according to its performance rules. The unexpected behavior appears at the boundary between them. An authorization policy that runs after shared work can leave the size or cost of that work correlated with private data. To decide whether the design isolates data, the review must therefore include plan selection and intermediate cardinality, not just the policy's logical condition.

The same reasoning avoids an overbroad conclusion.