31 Recipe: boot the headless-agent image and operate it
| Field | Value |
|---|---|
| Tool | kailash (headless-agent profile) |
| Section | Ops |
| Level | medium |
| Time | ~30 min (+ image download) |
| Layer/Category | OPS / o-07 |
| Tags | ops, headless-agent, grants, openssh, mcp-inspector, o-07 |
31.1 Problem
The agent-operated box is its own profile: headless-agent ships base + CLI with no desktop, small enough that the qcow2 can grow at first boot, and a grants system (o-07) that decides what an agent process may do. You want the boot → first-login → grants → MCP tooling loop that turns the image into a working automation host.
31.2 Solution
Build the image from the declared ref, boot it, then declare SSH and grants:
# 1. Build ref from the images table (or pull the release asset):
nix build github:kailash-os/kailash-os/2026.01-alpha.1#kailash-images-qemu-headless-agent
# (name shape: kailash-<tag>-kailash-headless-agent.qcow2)
# 2. Boot it in qemu with UEFI; disk is a GROWING qcow2 (≤1.5 GB
# budget is the boot-time floor — it grows at first boot)
qemu-system-x86_64 -m 2048 -bios edk2-x86_64-code.fd \
-drive file=kailash-<tag>-kailash-headless-agent.qcow2,format=qcow2
# 3. SSH is a DECLARED operator addition (not a default service):
# in configuration.nix:
# services.openssh.enable = true;
# services.openssh.settings.PermitRootLogin = "no";
# # + your hardening choices — the profile ships no SSH posture
# # by design; opening the daemon is yours to declare
# then: sudo nixos-rebuild switchThe grants system (o-07): every agent capability is a declared, time-bounded grant in /etc/kailash/grants/grants.json:
{
"holder": "scan-runner",
"categories": ["o-04"],
"tools": ["ollama"],
"allowExp": false,
"allowServiceStart": false,
"readOnly": true,
"notBefore": "2026-10-14T00:00:00Z",
"notAfter": "2026-10-15T00:00:00Z"
}# 4. Inspect the live grants store (deny-by-default, so absence=
# permission-withheld)
cat /etc/kailash/grants/grants.json
# 5. The one safe MCP surface: mcp-inspector (the o-07 row that is
# NOT exp-gated):
npx @modelcontextprotocol/inspector # upstream inspector flowExpected output shape (abridged, shapes not transcripts):
# boots to a text console (no desktop); login prompt on tty1
# grants store: JSON list of holders/categories/time windows
# inspector: browser UI on localhost:<port>(?)
31.3 Discussion
- The image budget is the boot-time floor: the ≤1.5 GB disk budget bounds the SHIPPED image; the qcow2 GROWS at first boot — budget the host disk for the growth, not just the download.
- SSH is deliberately not default: the profile ships no
services.opensshposture by design; a headless box you cannot reach is the safe default. Opening the daemon is a declared operator addition (in configuration.nix, reviewable, with your hardening choices on top) — never assume a live port 22 on a fresh headless-agent boot. - Grants, in their own words:
- deny-by-default: a capability is not present unless a holder grants it;
notAfterREQUIRED for any non-readOnlyholder: standing write/execute grants expire, by construction;- the grant system NEVER bypasses the double-key lab-mode gate — an exp tool is still exp-gated even for an agent holding a grant.
- Gate wrap applies to grants too: the o-07 exp MCP rows (
kailash-mcp,kailash-container, …) ride the SAMEkailash.safety.extraToolsgate-wrap as any exp row: opening them is a declared, double-key act, not a grant-holder act. - mcp-inspector is the safe surfacing: the one o-07 row that is NOT exp-gated — upstream’s own
npx @modelcontextprotocol/inspectorflow — the honest default for an agent host whose MCP needs are inspection, not capability expansion. - Responsible automation: the grants store is your audit trail. Prefer
readOnlyholders, time-window everything else, and keepallowExpfalse unless a lab pair (like the attack-defence recipes) needs it.
31.4 See also
- Boot a verified release image — the download/verification chain for the qcow2
- Choose between minimal, redteam-ai, full and headless-agent — when this profile is the right one
- Gate lab-mode and exp-classified tools — the gate grants never bypass
- The OS spec’s headless-agent + grants chapters: https://github.com/kailash-os/kailash-os/blob/master/docs/spec.md
- mcp-inspector upstream: https://modelcontextprotocol.io/
Recipe provenance. The profile facts (base+CLI only, hostname kailash-headless-agent, no desktop, qcow2 ≤1.5 GB growing at first boot, NO default openssh — a DECLARED operator addition, pkgs.kailash null-guard) and the grants contract (holders with categories/tools/allowExp/allowServiceStart/readOnly/notBefore/ notAfter, notAfter required for non-read holders, deny-by-default, grants never bypass the double-key gate) are the OS repo’s landed headless-agent profile + grants module, verified 2026-10-14. The mcp-inspector row is the one safe (non-exp) o-07 surface; exp MCP rows ride kailash.safety.extraTools gate-wrap. ref: headless-agent profile + grants module at master - verified 2026-10-14. Live boot smoke PENDING (wave-2 ops lane).