9 Recipe: gate lab-mode and exp-classified tools
Tool: kailash (safety classes, lab gate) · Section: Administrator · Level: medium · Time: ~20 min · Layer/Category: admin (cross-layer) · Tags: admin, safety, lab-mode, exp
9.1 Problem
Tools whose manifest row reads safety.level: exp — experimental code-execution surfaces like mlflow-bypass — ship in the catalogue but must be unreachable by default. You want to demonstrate the gate actually works on your host: a bare run refuses, a half-opened gate refuses, and only the deliberate double opt-in fires the tool.
9.2 Solution
The gate is double-keyed by construction: a host key (a NixOS option, baked into the gate wrapper at build time) plus a shell key (an env var on the individual invocation). Neither key alone ever suffices:
# 1. Who is exp-gated on this host? (the gate's state record)
cat /etc/kailash/safety/wrapped-exp-tools.json
# -> per wrapped id: {id, program, gate package}
# 2. Key 1 alone is NOT sufficient — lab host default is labMode=false:
# the wrapper refuses (exit 126) even WITH the shell key set
KAILASH_LAB_MODE=1 mlflow-bypass --help
# expected: refused; message names BOTH keys + cites
# docs/responsible-use.md
# 3. Open the HOST key (deliberate, reviewable config change) and rebuild:
# kailash.labMode = true; # in configuration.nix / your host module
sudo nixos-rebuild switch
# 4. Still gated: the shell key is the second, in-the-moment opt-in
mlflow-bypass --help
# expected: refused — the invocation did not set the shell key
# 5. BOTH keys on the same invocation -> the tool runs
KAILASH_LAB_MODE=1 mlflow-bypass --help
# expected: the tool's real help outputWhat success looks like:
- step 2 fails (host lab-off: the shell key alone is refused)
- step 4 fails (host lab-on: the missing shell key is refused)
- step 5 succeeds, and every refusal cites the responsible-use doc
- step 1’s state file lists the wrapped tools your closure carries, consumed by the parity validator, which independently re-parses the manifest to prove the wrapper set matches the exp row set
9.3 Discussion
- Why double-key: a single knob is a single mistake. The host key is a deliberate configuration act (reviewable in the system declaration); the shell key is an in-the-moment, per-invocation decision. Gate state commits to the closure — a rebuild without the host key removes the gate’s open path entirely.
- Gate data flows from the manifest, never a hand-copy: the exp-id list is scanned at eval from the declared manifest surfaces; the packaging-side generator emits the wrapper for every
safety.level: exprow — the manifest row IS the routing record. The parity validator re-parses the manifest with an independent implementation and proves coverage; a deliberately broken fixture is refused (proven in CI by construction). - There is no separate lab-mode distro: the same image carries both postures — the gate, not the package set, is what differs. A lab-off host is the default; opening the posture is the configuration change, and the per-invocation key stays the second.
- Legitimate lab enablement: with authorisation (see responsible-use), open the host key on lab machines, keep the shell key per-invocation, and prefer scoped invocations over standing open shells.
- Requires-target is a different, lighter gate: most ATTACK tools are
requires-target, not exp — they refuse to self-fire, run freely when given an explicit target. Attack the platform, then verify walks an exp-gated tool through this exact gate in a full pair run.
9.4 See also
- Safety classes chapter: https://docs.kailash.tools/governance/safety-classes.html
- Responsible use (the doc the refusal message cites): https://github.com/kailash-os/kailash-os/blob/master/docs/responsible-use.md
- The gate’s design decision — spec §9.2 (safety defaults) + spec §4.3 (the double-key gate): https://github.com/kailash-os/kailash-os/blob/master/docs/spec.md
- Recipe directory
Recipe provenance. The double-key mechanics (host option kailash.labMode, shell KAILASH_LAB_MODE=1, exit 126 wrappers, wrapped-exp-tools.json, refusal text citing responsible-use), the generator-parity contract and the manifest-routing statements are the landed gate contract per spec §9.2/§4.3 and the safety-exp-wrap validator, verified 2026-10-14 at master. behavioural transcript of each refusal/output: PENDING — the mechanism above is the verified contract; the worked host demonstration is the upkeep lane’s obligation.