Skip to content

Show what enforces a control

controls on a rule reads rule-first everywhere else. You write a rule and say what it is for, and every decision it makes carries those identifiers onto the audit record. A reader asking the question the other way round, “what enforces sa-pdpl:art-11 here”, has to go looking through the document for it.

kirto-gate controls is that inversion. One row per identifier, with every rule that names it, where those rules run, and what they apply to.

Point it at the same file the gateway reads:

Terminal window
$ kirto-gate controls -config kirto-gate.yaml
sa-pdpl:art-11 NOTHING ENFORCES IT
access_rules at llm "dead-claim" deny, where route is embeddings
never runs: "exempt" allows every request it would match; the controls it carries (sa-pdpl:art-11) are never recorded
sa-pdpl:art-29
guardrails "mask-email" redact, on every request, turning on annotations
sa-pdpl (Saudi Personal Data Protection Law): this document cites 2 controls, and no rule here names these
sa-pdpl:art-19 The controller takes organisational, administrative and technical measures to protect personal data, including during its transfer (Article 19).

It reads the document and nothing else. No listener, no raft log, no provider contacted, so it belongs in a pipeline. A ${secret:NAME} the cluster holds has a value stood in for it, as in kirto-gate check.

The clause after a rule is what that rule applies to, and it is answered only on the paths the document holds: the route labels, the declared providers, the profiles, the fronted servers and agents. Those are resolved before any rule runs, so the document settles them.

turning on names what the rule still depends on that the document does not hold: a key’s metadata, who the agent is, what a client sent, what the detectors found. Those are the request’s to answer, and the ledger leaves them named rather than guessing.

That is why no line says a control is enforced. What the command can say exactly is the negative, and the negative is the half people get wrong.

A control cited only by rules that never run is a claim with nothing behind it. The rule is in the document, its identifier is in the document, and no audit record will ever carry it, because an earlier rule takes every request it would have acted on. That exits non-zero, so a pipeline can hold a change on it.

A control a pack declares that no rule here names is the second. It is reported for every pack this document draws on, meaning every pack whose controls some rule still cites, and it does not change the exit status: removing a rule a pack brought is a decision an operator is allowed to make. A pack the deployment never added is not a gap and is not listed. Neither is a control the pack maps to a mechanism rather than to a rule, since no rule was ever going to carry it.

-json writes the same rows, with the applies-to as data rather than as a clause:

Terminal window
$ kirto-gate controls -config kirto-gate.yaml -json > controls.json

Each control carries its citations, each citation carries applies (the paths and values), open (what it still turns on) and dead (empty where the rule runs). uncited carries the pack gaps. The exit status is the same in either format.

Which keys exist. Keys live in the store, not the document, so a rule that applies to key.metadata.team == "finance" is reported as turning on key.metadata whether or not any key carries that. An offline read of a file cannot say otherwise, and a ledger that implied it could would be worse than one that says nothing.

Whether the rule is the right rule. The ledger says a rule names a control and what that rule applies to. Whether that rule is what the regime asks for is the reading a person does, which is why the packs carry the citation alongside each control.