Skip to content

Start from a control pack

A deployment under a regulatory regime needs a first set of rules that a reviewer can read, a proof that the rules decide what they say, and audit records that name the controls the reviewer tracks. A control pack is that first set, written down: rules for one regime, each naming the clause it serves, the suite that pins each decision, and a README saying what the pack does not cover. The binary ships a few; the format is open, and a pack of your own is added the same way.

A pack is copied, never switched on. kirto-gate pack add splices the pack’s detectors and rules into your deployment document, and after that the document is yours: edit any rule, and nothing reads the pack again. There is no packs: key, on purpose. A reading of a regime you switch on by name is one you inherit silently when it is wrong. A copy is one you read.

List the packs in the binary:

Terminal window
$ kirto-gate pack list
ID VERSION RULES CONTROLS TITLE
sa-ndmo 1 4 10 NDMO data classification
sa-pdpl 1 4 5 Saudi Personal Data Protection Law
sa-sama-csf 1 2 6 SAMA Cyber Security Framework
sa-sdaia-ai 1 1 6 SDAIA AI ethics and generative AI guidelines

kirto-gate pack show <id> prints one pack whole: its README, the controls it cites with a citation each, its attachments and mappings, and the fragment add would copy, comments included. That is everything there is. The README is the pack’s documentation. What a pack covers, what it leaves out and which text it read are said there, by the pack, and nowhere in these pages.

Point add at your deployment document, flags first and packs after, as in every command of this binary. Without -write it prints the merged document and touches nothing:

Terminal window
$ kirto-gate pack add -deployment deployment.yaml sa-pdpl
sa-pdpl: added guardrail_detectors/pii
sa-pdpl: added guardrail_rules/sa-pdpl-national-id
sa-pdpl: added guardrail_rules/sa-pdpl-contact-details
sa-pdpl: added guardrail_rules/sa-pdpl-financial-identifiers
sa-pdpl: added guardrail_rules/sa-pdpl-personal-data-recorded

The report goes to stderr and the document to stdout. Add -write to rewrite the file in place. Every line of your document that the pack did not add stays as it was, comments included, because the copy is a splice at each object’s own address rather than a re-render.

The merged document is compiled the way the gateway compiles it before anything is printed. A pack rule says requires: [pii], and a document whose only detector is called patterns gets a second detector named pii. If you would rather the pack’s rules read yours, add the pack, then rename or remove one of the two, and the compile at start will hold you to the result. Variables the document takes from the environment have to be set, as they do for kirto-gate check.

A deployment whose configuration lives in stored sources rather than in a file takes the pack the same way, through the admin API. Name the source with -source and the door with -socket or -url, as for kirto-gate admin:

Terminal window
$ kirto-gate login https://ai.example.com
$ kirto-gate pack add -source policy -url https://ai.example.com sa-pdpl
sa-pdpl: added guardrail_detectors/pii
sa-pdpl: added guardrail_rules/sa-pdpl-national-id
…
wrote source policy at revision 12

The source is read, the pack is spliced into its document exactly as into a file, and the result is written back at the revision that was read, so a change somebody else lands in between is refused rather than overwritten. A source that does not exist yet is created. Nothing is compiled on your machine: a source is a fragment of the deployment, and the gateway compiles the whole of it before the write lands, so a pack whose rules cannot build there is refused with the gateway’s reason and the source is untouched. The write is authorised object by object, like any write to that source, and the audit trail names you as its writer.

Name the source that owns guardrails. The block composes with one owner, so a pack added to a second source is refused with the two sources named; a deployment whose guardrails are still in a file-owned source moves them into a stored one first.

The write is a manager’s, the way kirto-gate config apply is. A source somebody else wrote last is refused naming them and what they changed since you last wrote it, because a source a tool applies takes its packs through the file that tool reads; -force writes over them. -dry-run sends the write with every check and stores nothing, which is how to read the gateway’s answer before the revision lands:

Terminal window
$ kirto-gate pack add -source policy -url https://ai.example.com -dry-run sa-ndmo
sa-ndmo: added guardrail_rules/sa-ndmo-classification
sa-ndmo: attached guardrail_rules/sa-pdpl-national-id
source policy would be written; nothing written, revision 12 stands

An object the document already has is compared with the pack’s by meaning, not by bytes, so your comments and quoting do not count as changes. Equal, it is kept and reported as already present. Different, the add is refused, names the object, and writes nothing:

Terminal window
$ kirto-gate pack add -deployment deployment.yaml -write sa-pdpl
kirto-gate: pack add sa-pdpl: pack: the document already has this object, with different content: guardrail_rules/sa-pdpl-national-id

That refusal is the pack’s update story. Adding the same pack twice changes nothing. Adding a newer edition of a pack lists the rules the edition changed, and you decide, rule by rule, whether your edit or the pack’s stands. Nothing follows a pack on its own, which is the property that makes copying it safe to do.

A pack may declare depends, the packs that have to be in the document first, and attach, its own control identifiers to put onto rules a base pack carries, so that one decision serves both regimes rather than two rules deciding the same thing. Name the base pack first, or add it earlier:

Terminal window
$ kirto-gate pack add -deployment deployment.yaml -write sa-pdpl sa-ndmo
sa-pdpl: added guardrail_detectors/pii
sa-pdpl: added guardrail_rules/sa-pdpl-national-id
…
sa-ndmo: added access_rules/sa-ndmo-classification-known
…
sa-ndmo: attached guardrail_rules/sa-pdpl-national-id += sa-ndmo:masking-before-sharing
sa-ndmo: already present guardrail_detectors/pii
wrote deployment.yaml

A decision under the attached rule now names both packs’ identifiers on its audit record. A pack whose base is absent is refused and names the pack to add first. Re-adding the base afterwards is still a no-op: the attached identifiers are read as the attachment they are, not as an edit of the rule.

A pack may also expect facts the document has to carry, such as metadata on a key or on a provider, and its README says which. A rule that reads a declared fact rather than a list of names is the shape that stays right when a key or a provider is added: the new one is refused until somebody writes the fact down.

Some controls no rule can enforce. A pack may map those to the mechanism that addresses them and the evidence it leaves, and pack show prints the mapping. It says where to look. Whether the control is met is yours to show.

Every rule carries controls, the identifiers the gateway writes onto each decision record, and every identifier has a citation in the pack. Read the pack’s README for what it read, what it decided and what it does not cover, and check the citations against the text your organisation is held to. A pack is a reading of a regime, not the regime.

Then hold the rules to your own cases. The pack’s suite is a file you can extend:

Terminal window
$ kirto-gate -config deployment.yaml -test-rules packs/sa-pdpl/kirto-gate.tests.yaml

The suite states findings rather than producing them, so it runs with no model and no detector asset. A pack’s suite is written against the pack and the packs it depends on. On a document that carries other packs too, a case can fail on a rule it never knew, because a second pack refuses a provider or a key the first pack’s cases never described. That failure is a fact about the merged document, which is what your own cases should state. To measure the detector on your own text, Measure a detector scores it against labelled cases at the offsets a rule would act on.

The regime you are held to may not be among the packs that ship, and a pack of your own is added the same way and held to the same checks. → Write a control pack

A pack cannot set anything but detectors, guardrail rules and access rules. Providers, credentials, keys, budgets, models and the guardrails block’s tuning are the deployment’s, and a pack that named them is refused. A pack cannot be a second configuration source either: guardrails composes as one block with one owner, so a pack’s rules have to be copied into the source that owns it rather than layered beside it, which is what -source does.