skip to content

Enforcement Decisions

What a no is worth once it leaves the engine: a violation caught after apply cannot be refused at all, and one caught before it can be waved through by a comment the author writes.

on this pageshow

questions

8

Why does a policy rule run over recorded infrastructure state catch violations a plan-time rule never will?

level: juniorimportance: must knowfreq 72%

answer

  1. look at what the input document contains
  2. a plan is a delta, not a census
  3. untouched resources appear in no plan
  4. state and inventory list what exists

basics

~20 s

A plan only contains the resources a change touches, so anything nobody is editing never appears in it. Running the same rule over recorded state or a cloud inventory judges every resource that exists, changed or not.

solid answer

~40 s

A plan document is a description of one proposed change: it lists the resources being created, updated, replaced or destroyed and nothing else. A rule fed that document can only ever judge what somebody happened to touch. If a database was created three years ago on an engine version that has since gone end-of-support, and no one has edited that resource since, it will never appear in any plan, so no plan-time run will ever evaluate it. Re-expressing the same rule over the recorded state file, or over an inventory export from the provider, changes the input to `everything that currently exists` — so the untouched population becomes visible. That is the whole reason teams run both: the plan check covers the change, the state check covers the estate.

go deeper

for a junior

Be ready to say what a plan document actually contains — only the resources this change touches — and therefore what a rule reading it can never see. Naming one example, such as an untouched end-of-support engine, is enough here.

for a middle

An interviewer expects you to distinguish the three inputs precisely: a plan is a delta, state is what this codebase manages, an inventory export is what the account holds. Say what each one misses.

for a senior

Show that you know the state run is scheduled rather than change-triggered, produces findings rather than a pass or fail, and needs a routing and closure workflow behind it before it is worth switching on.

for a principal

Own the argument that plan gates and state scans are different controls with different reach, and that measuring coverage as 'percentage of pipelines with the gate enabled' hides an estate nobody has ever evaluated.

## Two different documents A policy engine does not look at your infrastructure. It looks at a **document** describing your infrastructure, and everything the rule can decide is bounded by what that document contains. **The plan document** is a description of a single proposed change. For each resource involved it carries an address, a type, the action being taken (create, update, replace, destroy, or no-op) and the attribute values the resource will have afterwards. Crucially, a resource that the change does not touch is **not in the document at all**. The plan is a delta, not a census. **The recorded state** is the opposite shape. It is a record of every resource this codebase currently manages, with the attribute values each of them actually has. There is no change and no action in it, because nothing is being proposed — it is a snapshot of what is. **An inventory export** from the cloud provider is wider still: it lists resources in the account regardless of who created them or whether any codebase manages them. Resources created by hand, by another team's codebase, or by a tool that predates your pipeline appear here and appear nowhere else. ## The coverage gap this exposes If every rule you own runs only against plans, the set of resources you have ever actually evaluated is exactly the set somebody has changed since you turned the rules on. Everything else has been silently excluded. Two situations make this concrete: 1. **A resource nobody is changing.** A production database sitting on an engine version that has since gone end-of-support is a real risk — it stops receiving patches — but nothing about it is being deployed. It generates no plan, so it triggers no evaluation. It can stay invisible indefinitely, precisely because it is stable. 2. **A rule you added after the fact.** You write a new rule today. It applies to hundreds of existing resources, but it will only ever fire on the ones that happen to come up in a future change. The rest are grandfathered by accident, not by decision. Re-expressing the rule so it reads state or inventory closes both gaps in one move: the input becomes the population rather than the delta. ## What this looks like in practice A state-or-inventory run is normally **scheduled** rather than triggered by a change — nightly or hourly — because there is no change event to hang it on. Its output is not a pass or fail on somebody's pipeline; it is a set of findings about resources that already exist and are already running. Nothing is being deployed, so there is nothing to refuse. The finding lands in a queue and the response is a human workflow: annotate it, ticket it, fix it forward, or re-run the rule to show it is gone. ## Where each source stops - **State** covers what this codebase manages, and only that. A resource somebody clicked into existence in the console is not in your state file, so a state-only scan will miss it entirely. - **Inventory** covers the account, so it sees the hand-made resources too — often the worst offenders, because they never passed through any pipeline. But it is provider-shaped rather than code-shaped, so the addresses in the findings do not map neatly back onto modules and repositories, which makes routing harder. Most mature setups read both, and treat a resource that appears in inventory but not in state as a finding in its own right. ## The thing to say in an interview The plan gate and the state scan are not two implementations of the same control. The plan gate is the only one that can act **before the resource exists**, and it gives feedback inside the author's own change. The state scan is the only one whose input includes the resources nobody is touching, which is where long-lived risk accumulates. Keeping only the first gives you a green pipeline over an estate you have never examined; keeping only the second means every violation is discovered after it is already running.

  • Give a concrete violation a plan-time rule structurally cannot find.
    A production database on an engine version that went end-of-support after it was provisioned. Nobody has edited the resource, so it appears in no plan and no plan-time run ever evaluates it. The same applies to any rule written after a resource was created: it only fires if that resource happens to come up in a future change.
  • If the state scan covers everything, why keep the plan-time check at all?
    Because the state scan runs after the resource exists. Its finding arrives when the thing is already deployed and serving traffic, so closing it needs a ticket, an owner and a maintenance window. The plan check acts while the change is still a proposal and gives the author feedback inside their own change, where fixing it costs an edit.
  • Does a resource have to be in the state file to be scanned?
    No. State covers only what this codebase manages. An inventory export from the provider also covers resources created by hand or by another codebase — often the ones with the worst findings, because they never passed through a pipeline. A resource present in inventory but absent from state is itself worth flagging.

A plan is the delivery note for today's shipment. State and inventory are the warehouse stocktake. Reading only delivery notes never tells you what has been sitting on the shelf for three years.

saying these in an interview costs you the question

  • Believes a plan document lists the whole estate
  • Treats a green pipeline as proof the estate is clean
  • Assumes every resource eventually shows up in some plan
  • Confuses state coverage with full account inventory coverage

context

open as a page

A pull request adds an inline Checkov skip comment whose reason you cannot verify — how do you review it?

level: seniorimportance: must knowfreq 52%

basics

~20 s

Review the skip as the change, not the comment: decide whether the finding is real or a rule bug, insist on the narrowest form, require a reason checkable in the same diff, and remember an annotation has no expiry and no approver.

open as a page

In Checkov, what does a #checkov:skip comment inside a Terraform resource block do?

level: juniorimportance: should knowfreq 58%

basics

~20 s

A checkov:skip comment suppresses one named check for the single block it sits inside. The form is checkov:skip=CHECK_ID:reason; the reason is free text nothing validates, and the finding is reported as skipped rather than failing the run.

open as a page

What does a plan-time policy rule lose when you re-express it against recorded state or an inventory?

level: middleimportance: should knowfreq 58%

basics

~10 s

It loses the change action, the prior value, the surrounding request context that identified the author, and the implicit scope of only judging touched resources. A state record is attributes with no verb attached.

open as a page

When should a Checkov exemption be an inline skip comment rather than a config-file skip-check or skip-path?

level: middleimportance: should knowfreq 45%

basics

~20 s

An inline skip fits one resource that legitimately violates one check: narrow, and visible in the diff. Use skip-check or skip-path only when the rule or path is wrong for the whole scan, since both are invisible at the violating line.

open as a page

A post-apply policy scan flags an end-of-support database engine in production — how do you choose what the finding triggers?

level: seniorimportance: should knowfreq 46%

basics

~20 s

Nothing is deploying, so no gate can refuse it — the finding only starts a human workflow: an expiring exception, an owned ticket with a date, or a fix shipped through code. A clean re-run is the closure.

open as a page

An auditor wants proof that last quarter's policy finding is closed — why isn't the closed ticket enough?

level: seniorimportance: nice to knowfreq 31%

basics

~10 s

A ticket records that someone said they fixed it. Proof is the same rule, re-run over current state, no longer returning that resource — shown alongside the earlier run that did return it.

open as a page

How do you find every live Checkov suppression across your Terraform repos, and spot the stale ones?

level: seniorimportance: nice to knowfreq 28%

basics

~20 s

Collect two sources, not one: every inline skip annotation in the source, and every skip-check, skip-path and skip flag in scan configuration and pipeline definitions. Then age each one with git history and the scan's skipped-checks output.

open as a page