skip to content

What the Engine Sees

An engine sees the change under evaluation plus whatever context it was handed. Replicating context in keeps decisions fast and stale; fetching it mid-decision turns the rule into a program.

on this pageshow

questions

3

In a policy decision, what separates the change under evaluation from the surrounding facts?

level: juniorimportance: must knowfreq 72%

answer

  1. two documents, not one
  2. the proposal versus the standard
  3. the allow-list is not in the plan
  4. could the author edit it true?
  5. claims come from the gated party

basics

~20 s

The change under evaluation is the document being decided on, such as a proposed plan or manifest. The surrounding facts are everything else the rule needs, like the list of approved instance types, which the change never carries.

solid answer

~50 s

A policy engine evaluates a document it is handed, and that document has two halves. The **change under evaluation** is what the author proposes: a plan to create an instance, a manifest, a job definition. The **surrounding facts** are what the rule must compare it against, and they are not properties of the change at all: which instance types are approved, which regions the company may run in, who owns which namespace. A rule like "only approved instance types, only approved regions" reads `m5.24xlarge` and `eu-central-1` straight out of the plan, but the approved lists appear nowhere in it and never will. The useful test is: could the change's author make this predicate true by editing their own file? If yes, it is a claim from the party being gated, not a fact. The change is untrusted input; the fact set must arrive by a path the author does not control.

code

json · 15 lines
json
{
  "resource_changes": [
    {
      "address": "aws_instance.batch",
      "type": "aws_instance",
      "change": {
        "actions": ["create"],
        "after": {
          "instance_type": "m5.24xlarge",
          "availability_zone": "eu-central-1a"
        }
      }
    }
  ]
}

go deeper

for a junior

Be ready to state plainly that a decision compares two things: the change being proposed and the facts it is judged against. Know that the second half is supplied separately and is not hiding inside the plan or manifest.

for a middle

Explain why a value the change's own author controls is a claim rather than a fact, and give an example of a fact the change cannot carry at all, such as current account spend or an approval recorded elsewhere.

for a senior

Show that you decide this split deliberately for each rule, and that you have thought about what the gate does when the fact set is missing or empty rather than assuming it will always be there.

for a principal

Own the question of who maintains each fact set and by what review path, since the trust in every fact-driven rule reduces to whether the gated party can influence the standard they are measured by.

## Two halves, not one document A policy engine does not "look at your infrastructure". It evaluates a document that something hands it, and that document splits into two conceptually different halves. Confusing them is the first mistake a new policy author makes, and it survives into surprisingly mature gates. The **change under evaluation** is the thing being decided on: a proposed plan for infrastructure, a manifest about to be admitted to a cluster, a pipeline job definition, an image's metadata. It is authored by the person the gate exists to constrain, and it describes what they want to happen. It is self-contained and self-describing. The **surrounding facts** are everything else the rule needs to turn that description into a verdict. Which instance types finance has approved. Which regions the company is permitted to operate in. Which cost-centre codes are valid this quarter. Which team owns which environment. None of that lives in the change, and none of it can, because it is not a property of the change. It is a property of the organisation at the moment the change is judged. ## The worked case Take a rule that says: an instance may only be created with an approved type, in an approved region. The plan carries an instance type and an availability zone. Extracting those two values is trivial. The rule still cannot decide anything, because the interesting half of the comparison, the *set* of approved types and the *set* of approved regions, is nowhere in the plan. The change says what is wanted. The fact set says what is permitted. A decision is the comparison. An engine given only the first half can answer only trivial questions such as "is an instance type set at all?". ## The test that separates them Ask one question of every value your rule reads: > Could the author of this change make my predicate true by editing their own file? If the answer is yes, that value is part of the change, and it is a **claim**, not a fact. A manifest carrying a label reading `approved: true`. A plan with a tag declaring `environment = "dev"` so the production rules skip it. A build that states its own risk tier. Each of these is an assertion written by exactly the party the gate constrains. A rule that trusts one has not been defeated by a clever attacker; it was written to ask the gated party for permission. This is why the split is a security property rather than a modelling nicety. The change is untrusted input. The fact set is trusted, and it earns that trust from *where it comes from*: a list a different group maintains, reviewed on a different path, delivered to the engine by something the change's author cannot edit. That does not make every value in the change useless. Values that describe what will actually be created, the instance type that will be provisioned, the image that will run, are exactly what you want to gate on, because the platform will honour them. What you must not do is let the change also supply the *standard* it is judged against. ## Facts a change can never carry Some facts are not merely absent from the change; it is structurally impossible for the change to carry them. How many instances the account already runs. What has been spent this month. Whether a human approved this in a ticketing system. Whether the same rule denied this yesterday. A change is a description of one proposed state, so anything about *the rest of the world*, or about *history*, has to arrive from somewhere else, or the rule cannot be written at all. Spotting early which of your intended rules need such a fact is what tells you whether a gate is cheap or expensive to build, long before anyone writes a line of rule. Broadly there are three ways to get such a fact in front of the engine: replicate it into the engine ahead of time so it is loaded alongside the rules, have the caller collect it and pass it in with the change, or have the engine look it up during evaluation. They buy very different freshness and very different failure behaviour. ## Where this goes wrong in practice - Writing a rule against whichever field the change happens to carry today, without ever deciding whether that field is a claim or a fact. - Assuming the engine can see the world. Most engines see only what they were given. - Degrading quietly when the fact set does not arrive. Many rules, deprived of the list they compare against, produce no opinion rather than a denial, and a gate with no opinion lets the change through. - Treating "the engine saw it" and "the engine was told it" as the same statement. Only the second is ever true. ## What good looks like Before writing the rule, name the two halves out loud: this is the change, these are the facts, and this is who maintains each. Nearly every hard question later in a gate's life, staleness, reproducibility, who may edit the allow-list, is a consequence of that one split being drawn deliberately rather than by accident.

  • The plan already names its region, so why is that not enough to decide whether the region is allowed?
    Because the plan states what the author wants, not what the organisation permits. The region name is one operand; the approved-regions set is the other, and it lives outside the change. Without it the rule can only check that a region is present at all, which denies nothing anybody cares about.
  • A manifest carries a label saying it was approved. Can a rule act on that?
    Only as a signal, never as the fact. The author of the manifest writes that label, so it is a claim by the party being gated. If approval matters, the record of it has to come from wherever approvals actually live and be supplied to the engine on a path the author does not control.
  • What happens to a rule when the fact set fails to arrive?
    Usually nothing visible, which is the danger. A comparison against a missing or empty set often yields no denial rather than a denial, so the gate silently turns into a pass-through. Decide explicitly what absent facts mean and make the engine or its caller fail loudly instead of quietly allowing.

A passport control officer reads your passport, but the watch-list is not printed inside it. The traveller supplies the claim; the state supplies the standard.

saying these in an interview costs you the question

  • Thinks the approved-types list is somewhere inside the plan
  • Assumes the engine can query the cloud account by itself
  • Trusts a label the change's own author wrote
  • Cannot say where a fact outside the change comes from
  • Says a missing fact set makes rules deny by default

context

open as a page

How can a policy engine get a fact, such as an approved-region list, that the change never carries?

level: middleimportance: should knowfreq 58%

basics

~10 s

Three routes: replicate the fact into the engine ahead of time, have the caller pass it in with the change, or look it up live during evaluation. Each buys different freshness and fails differently.

open as a page

Your policy gate denied an unchanged plan at 09:00 and allowed it at 10:00 — what happened, and what do you change?

level: seniorimportance: should knowfreq 44%

basics

~20 s

The plan did not move; the facts around it did. Someone edited the approved list, or a live lookup answered differently. Pin the fact set to an identifiable revision and name it in every verdict.

open as a page