All lessons › Function B — Securing AI Architectures › Securing the Architecture — Runtime and the Gateway
B3.9

Turning a control off without turning the system into an experiment

B3
▶
Lightboard recording

Not recorded yet. The lesson below is complete and runnable today — the video is added later without touching this page.

Video placeholderpublishes automatically from recordings/B3.9.mp4
Risk

Classifiers off, no compensating cap, and tens of thousands of agents launched under that configuration. Each decision was defensible; the combination was never evaluated.

Control

An exemption gate the platform enforces (C6.1), caps that tighten as coverage drops (C6.2), quotas on population and lifetime (C8.2), and an exemption register reviewed at fleet-launch approval (C6.4).

The lab

Disable a classifier without an approved exemption and watch the platform refuse; then launch 50,000 agents under one that is approved.

◉Use case relevance

Turning the cyber classifiers off for a cyber evaluation was defensible. Launching tens of thousands of agents was a normal request. Nothing in the path required the two decisions to be considered in the same sentence, and the combination was never evaluated by anyone.

At CyberTravels. policy.Exemption, which refuses to exist without a reference, a reason, an approver and an expiry. decide() lets an active one lift an obligation and still names it in the decision; expired() counts the ones that ran out and are still in the file, which is a control set describing a system nobody is running.

◴What this lesson is — Day 0, Day 1, Day 2

Turning a control off as a recorded, scoped, expiring decision — a reference, a reason, a named approver and an end date, none of them optional — and counting the exemptions that have run out and are still in the file, which is a control set describing a system nobody is running.

Day 0 — why

Classifiers off, no compensating cap, and tens of thousands of agents launched under that configuration. One decision becomes a population-scale incident.

Day 1 — how

An exemption gate the platform enforces, caps that tighten as coverage drops, and quotas on population growth.

Day 2 — measure

Live exemptions, the age of each, and the cap in force while it is open.

Measure this

what to measuredenominator or target
live exemptionscount
age of each exemption, and the cap in force while it is opendays, and the cap

▦The framework, and how it works

   coverage                    permitted blast radius

   all controls on             50,000 agents . 72h . allowlist+
   one detective off              200 agents .  8h . allowlist
   two or more off                 25 agents .  2h . allowlist

        exemption record ----> orchestrator ----> refuse or terminate
        (control, scope, expiry,        (caps are charged, not remembered)
         compensating control)

Controls get disabled. A classifier blocks the evaluation you are trying to run; an egress rule breaks a legitimate integration; a rate limit makes a test impossible. Pretending otherwise produces shadow exemptions rather than fewer of them.

What makes an exemption safe is not the approval. It is that reduced detective coverage automatically buys a smaller blast radius, enforced somewhere the workload cannot reach.

In the source incident that link was absent. Cyber classifiers were turned off for a cyber evaluation — defensible on its own — and tens of thousands of agents were then launched under that configuration, with no compensating cap. The report assesses the classifiers would likely have blocked many of the attack actions. Each decision was reasonable; the combination was never evaluated, because nothing forced the two to be considered together.

Four controls:

The exemption gate (C6.1). A written record naming the control, the scope, the justification, the compensating control and a hard expiry — and it must be technically enforced. If the platform cannot express the exemption, it cannot be granted.

Blast-radius caps (C6.2). Egress allowlist, concurrency, runtime, spend and target scope, defaulting tighter as coverage decreases, enforced in the orchestrator and terminating on breach rather than alerting.

Population and lifetime quotas (C8.2), tied to the exemption state so reduced monitoring lowers them automatically.

A register reviewed at launch (C6.4). Scale is the variable that changes the risk: the same exemption is fine at 100 agents and unacceptable at 50,000.

2 · An exemption the platform can read

3 · Where it breaks — the combination nobody evaluated

4 · The control — caps that tighten as coverage drops

5 · Verify — compounding, which is where the risk actually sat

6 · The check, as a skill

Alex turned the guardrails off for the demo, and that was defensible. The skill checks what made it defensible — a bounded exemption the platform can read — and then decides the same launch twice: control by control, and against the exemption class. The two answers disagree, and that is the finding.

▶Real time execution as skill

The skill — skills/runtime/control-exemption-audit/SKILL.md

name: control-exemption-audit
description: >-
  Check that turning a control off is a recorded, bounded exemption the platform
  reads, and that risky launches are decided against the exemption class rather
  than one control at a time. Use when guardrails are disabled for a demo, a
  migration, or a load test.
allowed-tools: Read, Grep, Glob

Turning a control off is defensible; not recording it is not

Every estate disables controls sometimes. The failure is not the disabling — it is that nothing recorded it, nothing bounded it, and the next decision was made by a system that believed the control was on. And decisions made one control at a time approve launches that the same facts refuse when taken together.

When to use this

Reviewing guardrail configuration, change management for agent platforms, or any launch where "we turned that off for the demo" appears in a thread.

Procedure

1 — Compare intended state with actual state, per control. The gap is the set of undeclared exemptions, and each one is a finding regardless of whether it was reasonable.

2 — Require the exemption to be a record the platform reads. Control, requester, approver, reason, expiry. A record in a ticket the platform cannot read is documentation; the orchestrator must refuse a disable with no matching record.

3 — Test both directions. A named control with a valid exemption may be disabled. A control with no approval must be refused. Both, or it is a logging system.

4 — Decide a launch one control at a time. Take a large launch and evaluate each control's own rule. It will be approved, and each answer will be correct in isolation. Record that.

5 — Re-decide against the exemption class. Group the disabled controls — detective, preventive, egress — and set caps per class: how many agents, for how long, with what compensating control. The same launch is now refused, and a smaller one on an allowlist is permitted. The disagreement between step 4 and step 5 is the finding.

Example

Input — the fixture committed at the top of scripts/control_exemption_audit.py. Edit it and re-run: the buckets, counts and verdicts below are derived from it, not hard-coded.

Output — the opening lines of a real run:

day  12  disable cyber-classifier    ALLOW via EX-118
day  44  disable cyber-classifier    REFUSE - no approved exemption
day  12  disable transcript-signing  REFUSE - no approved exemption

The record is the mechanism, not a wiki page describing one. An
exemption the platform cannot express is an exemption you cannot grant.
checked one decision at a time:
   exemption valid : True

The run continues past this. test_skills.py executes the script on every build, with no model configured — so what CI proves is that it runs and refuses legibly, not that it prints these lines. The output above is a recorded run against a real model, and nothing re-diffs it: a model's answer is not reproducible, and this repository does not claim otherwise anywhere it can be checked.

Output contract

{
  "controls": [{"name": "str", "intended": "on|off", "actual": "on|off", "exemption": "str|null"}],
  "exemptions": [{"control": "str", "approver": "str", "expires": "str", "platform_readable": true}],
  "probes": {"named_with_approval": "permitted", "unapproved": "refused"},
  "launch": {"request": {"agents": 0, "hours": 0}, "per_control_verdict": "approved",
             "by_exemption_class_verdict": "refused", "caps": {"class": "str", "agents": 0, "hours": 0}}
}

Failure modes

  • An exemption the platform cannot read. It cannot enforce an expiry it cannot see.
  • Deciding control by control. Each answer is right and the composition is wrong.
  • No expiry. A permanent exemption is a policy change made by whoever was on call.

Three ways to do this lesson. Pick one. They run the same procedure against the same code — what changes is who drives it, and how much you see.

1In your AI agent — you are taught

The agent reads the lesson, explains the idea, fetches the code, runs the check and answers your questions as you go. This is the one to take if you are here to learn.

Install it, once. From the folder you cloned. --all does every agent it finds on your machine:

python3 scripts/install_skills.py --all --lessons B3.9

Then restart your agent and open it in that folder. On Windows, if python3 says Python was not found, use python instead.

Then pick b3-9-turning-a-control-off-without-turning:

agentinstall just for this agentstart it
Claude Codepython3 scripts/install_skills.py --tool claude --lessons B3.9type /b3-9-turning-a-control-off-without-turning
GitHub Copilot (VS Code)python3 scripts/install_skills.py --tool copilot --lessons B3.9type /b3-9-turning-a-control-off-without-turning in Chat
Cursorpython3 scripts/install_skills.py --tool cursor --lessons B3.9type / in Agent chat and search for it
Codexpython3 scripts/install_skills.py --tool agents --lessons B3.9type $b3-9-turning-a-control-off-without-turning, or run /skills

2As one Python command — you just run it

No agent, no conversation. The same lesson executes and prints the same readback. Take this one if you have no assistant, if you are reviewing rather than learning, or if you want the result without the teaching around it.

python3 scripts/lesson.py B3.9

3Read the code, and the difference — nothing runs

Neither of the above, and no model needed. The first command writes CyberTravels exactly as it stood at the end of this lesson; the second prints the diff — the lines this lesson added or changed, and nothing from any later one.

python3 scripts/checkpoint.py --at B3.9 --out work/cybertravels
python3 scripts/checkpoint.py --at B3.9 --diff

On Windows, type python wherever these say python3 — and use \ instead of / in the paths. Everything else is identical. A0.0 step 2 explains why.

Ways 1 and 2 need a model; way 3 does not. A signed-in Claude Code CLI needs no API key, and any OpenAI-compatible endpoint works too. With neither, the audit exits 2 and says so rather than inventing an answer. A0.0 sets this up.

Ways 1 and 2 both end with the same readback: What I did, What changed, The number and Read this next. A step that was skipped or refused is reported as exactly that, never as a pass.

If you did the last lesson’s challenge, expect this to stop. Most challenges ask you to edit the code, and ways 1 and 2 will not overwrite your edits: you get stopped, not a failure, with two options — --out for a fresh folder that keeps your work, or --force to discard it and start this lesson clean.

✓What you just proved

An exemption record the platform reads permits disabling one named control and refuses another with no approval. Checked one decision at a time, a 50,000-agent launch with classifiers off is approved — both answers correct in isolation. Tied to exemption class, the same launch is refused and 200 agents for 8 hours on an allowlist is permitted; a second exemption drops the cap again, from 200 to 25.

✎Your turn

Find one control currently disabled in your environment and ask three questions: who approved it, when does it expire, and what cap came with it. The third question is the one that usually has no answer.

Tools used

OPAKyverno

Skill source: skills/runtime/control-exemption-audit

← PreviousB3.8 · Shared infrastructure between agent runs