Reference runtime
Stage, provision, and preflight the reference security topology on one Linux host, then start it in the order its authority requires.
On this page
The end state is one Linux x86_64 host running the trust control plane, a remote MCP edge, the secret broker, and five key-log services under systemd, each under its own account. The edge serves one confined reader of the pricing repository, and only after chio security preflight --require-enforcement has passed over its exact launch.
The package ships in the release's reference-runtime archive: five systemd units, sysusers.d/chio.conf for the four service accounts, and tmpfiles.d/chio.conf for the configuration and credential directories. Every unit is Type=notify, and every ExecStart= runs through chio security supervise, which delivers the unit's credentials from systemd's credentials directory, reports readiness only once the service answers, and forwards stop signals so the service drains.
Four accounts own four sets of state
sysusers.d declares chio-trust, chio-edge, chio-broker, and chio-keylog, one per service family, so a process under one account reaches only its own stores and credentials. The three witnesses and two audit monitors share chio-keylog: separate directories, one UID. Service roles.
1. Stage the ten executables
On a Linux x86_64 host with systemd and the cage prerequisites, download the reference-runtime archive for the release, verify it, and unpack it into an empty stage directory. The archive holds the ten executables the stage needs, a copy of the reference-runtime package, and native-runtime.json.
curl -fsSLO https://github.com/backbay-labs/chio/releases/download/v0.2.0/chio-reference-runtime-0.2.0-x86_64-unknown-linux-musl.tar.gz
chio release verify chio-reference-runtime-0.2.0-x86_64-unknown-linux-musl.tar.gz
mkdir -p ./stage
tar -xzf chio-reference-runtime-0.2.0-x86_64-unknown-linux-musl.tar.gz -C ./stagearchive chio-reference-runtime-0.2.0-x86_64-unknown-linux-musl.tar.gz checksum ok signed by release.yml on backbay-labs/chio, issuer token.actions.githubusercontent.com provenance SLSA v1, tag v0.2.0, subject present verified
You should see the archive verified before you unpack it, then the ten executables, reference-runtime/, and native-runtime.json in ./stage. Every executable is x86-64. The musl helpers are static, with no interpreter and no NEEDED, RPATH, or RUNPATH entry: a cage helper's signed filesystem grants include no loader. Building the same stage from a tagged source tree is covered in build from source.
| Build target | Executables | Static |
|---|---|---|
x86_64-unknown-linux-gnu | chio, chio-secret-brokerd, chio-active-response-authorityd, chio-keylog-witness, chio-keylog-audit | No |
x86_64-unknown-linux-musl | chio-cage-init, chio-broker-mcp, chio-tool-repo-reader, chio-tool-artifact-writer, chio-tool-digest | Yes |
2. Install the binaries, accounts, and units
Install the staged binaries and declarations as the host administrator. This creates the accounts and directories; it provisions no credential and starts nothing.
cd stage
sudo install -m 0755 chio chio-secret-brokerd chio-active-response-authorityd chio-keylog-witness chio-keylog-audit chio-broker-mcp /usr/local/bin/
sudo install -d -m 0755 /usr/local/libexec/chio /etc/sysusers.d /etc/tmpfiles.d
sudo install -m 0755 chio-cage-init chio-tool-repo-reader chio-tool-artifact-writer chio-tool-digest /usr/local/libexec/chio/
sudo install -m 0644 reference-runtime/sysusers.d/chio.conf /etc/sysusers.d/chio.conf
sudo install -m 0644 reference-runtime/tmpfiles.d/chio.conf /etc/tmpfiles.d/chio.conf
sudo systemd-sysusers chio.conf
sudo systemd-tmpfiles --create chio.conf
sudo install -m 0644 reference-runtime/systemd/*.service /etc/systemd/system/
sudo systemctl daemon-reloadYou should see the four service accounts and the five units listed in units and their start checks. Provisioning also needs:
- a readable
/srv/larkfield/pricing, and a private/var/lib/chio-mcp-edgeowned bychio-edge; - an existing canonical
/srv/chio-receipt-anchors/mcp-edgeon a persistent device separate from the receipt database, retained apart from database snapshots; - distinct bearer roles, the reviewed policy and public pins, and the broker credentials.
3. Provision the launch in Shadow, then Enforced
chio security provision-reference-runtime writes the signed launch material for one confined tool and promotes a migration ledger to the requested --stage, shadow or enforced (the default). Run the Shadow stage from an unprivileged account to discover the tool list, then the Enforced stage as root with the reviewed list:
sudo install -d -o "$(id -un)" -m 0700 /srv/chio-provision
chio security provision-reference-runtime \
--stage shadow \
--output-dir /srv/chio-provision/shadow \
--cage-init /usr/local/libexec/chio/chio-cage-init \
--max-artifact-bytes 67108864 \
--discover-tools \
--target /usr/local/libexec/chio/chio-tool-repo-reader \
--target-arg --root --target-arg /srv/larkfield/pricing \
--read-path /srv/larkfield/pricing \
--execution-uid "$(id -u chio-edge)" --execution-gid "$(id -g chio-edge)" \
--server-id workspace --server-name "Larkfield pricing workspace" --server-version 1
sudo chio security provision-reference-runtime \
--stage enforced \
--output-dir /etc/chio/mcp-edge/provision \
--runtime-security-dir /var/lib/chio-mcp-edge/security \
--cage-init /usr/local/libexec/chio/chio-cage-init \
--max-artifact-bytes 67108864 \
--receipt-rollback-anchor-root /srv/chio-receipt-anchors/mcp-edge \
--tools-fixture /srv/chio-provision/shadow/reviewed-tools.json \
--target /usr/local/libexec/chio/chio-tool-repo-reader \
--target-arg --root --target-arg /srv/larkfield/pricing \
--read-path /srv/larkfield/pricing \
--working-directory /var/lib/chio-mcp-edge \
--execution-uid "$(id -u chio-edge)" --execution-gid "$(id -g chio-edge)" \
--server-id workspace --server-name "Larkfield pricing workspace" --server-version 1You should see a chio.reference-runtime-provision-report.v1 report per stage, kept as provision-report.json in its output directory. Shadow reads shadow_legacy_authorized with containmentEnforced false, and --discover-tools recorded the target's tools/list as reviewed-tools.json. Enforced reads enforced_cage with containmentEnforced true, a statement about the material, not a running service.
Provisioning builds its material beside the output directory and renames it into place, so the parent must exist and be writable. A rerun with the same inputs prints the same report, and changed inputs are refused with the material unchanged, so give each stage its own directory. The material binds the executable's digest and the read grant; to change the tool or widen the repository root, provision again into a new directory. Keep the Enforced directory root-only: it holds the operator's private signers. Shadow migration covers the signed transitions the ledger records.
4. Install the launch state the edge opens
Copy the provisioned files to the exact paths the unit opens. The migration ledger and receipt signer go to the edge with private permissions; the other provisioning signers stay under operator custody.
sudo install -d -m 0750 -g chio-edge /etc/chio/mcp-edge/launch
sudo install -m 0640 -g chio-edge \
/etc/chio/mcp-edge/provision/{signed-manifest.json,cage-launch-policy.json,cage-migration-genesis.json,cage-migration-shadow.json,cage-migration-enforced.json,reviewed-tools.json,target-command} \
/etc/chio/mcp-edge/launch/
sudo install -d -m 0700 -o chio-edge -g chio-edge /var/lib/chio-mcp-edge/security
sudo install -m 0600 -o chio-edge -g chio-edge \
/etc/chio/mcp-edge/provision/{enterprise-migration.sqlite3,cage-receipt-signer.seed} \
/var/lib/chio-mcp-edge/security/
sudo install -m 0640 -g chio-edge /etc/chio/mcp-edge/provision/{manifest-public-key,cage-migration-public-key,cage-receipt-public-key,control-authority-public-key} \
/etc/chio/mcp-edge/provision/cage-policy-signer /etc/chio/mcp-edge/launch/
sudo install -m 0640 -g chio-edge deploy/reference-runtime/env/chio-mcp-edge.env.example \
/etc/chio/mcp-edge/chio-mcp-edge.env
sudo install -m 0640 -g chio-edge your-policy.yaml /etc/chio/mcp-edge/policy.yamlFill the environment file with the manifest and cage-policy public keys, the trust control authority key, CHIO_MCP_SERVER_ID=workspace, and the upstream command /usr/local/libexec/chio/chio-tool-repo-reader --root /srv/larkfield/pricing. The keys are public pins; bearer values stay in the supervisor's credential inputs.
5. Preflight the exact launch
Set CHIO_MANIFEST_PUBLIC_KEY and CHIO_CAGE_POLICY_SIGNER from the provisioning record, then run preflight with the edge's four credential inputs, session store, and wrapped command. The supervisor injects bearer values outside the process arguments.
sudo systemd-run --wait --pipe --collect \
-p LoadCredential=session-token:/etc/chio/credentials/edge-session-token \
-p LoadCredential=admin-token:/etc/chio/credentials/edge-admin-token \
-p LoadCredential=control-token:/etc/chio/credentials/edge-control-token \
-p LoadCredential=workload-token:/etc/chio/credentials/edge-workload-token \
-p User=chio-edge \
/usr/local/bin/chio security supervise --exec \
--credential-env CHIO_AUTH_TOKEN=session-token \
--credential-env CHIO_ADMIN_TOKEN=admin-token \
--credential-env CHIO_CONTROL_TOKEN=control-token \
--credential-env CHIO_REMOTE_AUTHORITY_WORKLOAD_TOKEN=workload-token \
-- /usr/local/bin/chio --session-db /var/lib/chio-mcp-edge/sessions.sqlite3 \
security preflight --require-enforcement \
--signed-manifest /etc/chio/mcp-edge/launch/signed-manifest.json \
--manifest-public-key "$CHIO_MANIFEST_PUBLIC_KEY" \
--cage-policy /etc/chio/mcp-edge/launch/cage-launch-policy.json \
--cage-policy-signer "$CHIO_CAGE_POLICY_SIGNER" \
--server-id workspace \
-- /usr/local/libexec/chio/chio-tool-repo-reader --root /srv/larkfield/pricingYou should see four probe lines, the platform, the bearer roles, the signed native launch, and the session store, and a summary line with exit code 0. Keep the report and its exit status with the deployment record.
6. Start the units and confirm readiness
Start the services in authority order, then read their state and the edge's journal:
sudo systemctl start chio-trust-control.service
# Other configured services require their own custody and runtime authority.
sudo systemctl start chio-secret-broker.service
sudo systemctl start chio-keylog-witness@a.service chio-keylog-witness@b.service chio-keylog-witness@c.service
sudo systemctl start chio-keylog-audit@a.service chio-keylog-audit@b.service
sudo systemctl start chio-mcp-edge.service
systemctl show chio-trust-control.service chio-mcp-edge.service chio-secret-broker.service \
-p ActiveState -p SubState -p Result -p ExecMainStatus
sudo journalctl -b -u chio-mcp-edge.service --no-pagerYou should see ActiveState=active and SubState=running for each unit, which a Type=notify unit reaches only after its supervisor observed the readiness endpoint. Then run the useful read and its refused outside-root neighbor from deployment hardening and the allowed and refused application procedure, and retain the responses, receipts, and independent file observations.
A preflight report names the probe and the exit code
chio security preflight runs four probes in a fixed order on the probe framework of chio doctor (node preflight). Each probe checks only what it is given and prints one line: a severity marker, the probe name, a registry code in parentheses, and a message, then indented help: and context lines. Probe severities lists when each probe reports ok, info, warning, or error.
The summary gives the worst severity and the exit code, 0 for ok, info, or warning, 1 for error, 2 for fatal, and the process exits with it. Without --require-enforcement a missing prerequisite is only a warning, so a bare run exits 0 on any host; pass the flag wherever the exit status gates a confined launch. The bearer-role probe reads its variables whatever flags are given, so a bad token in the environment fails even a bare run.
The units act on that exit status. Trust control's ExecStartPre= preflight fails the unit on a damaged store instead of rebuilding it. The edge's runs with --require-enforcement under chio security supervise --exec, which first places the four bearer credentials in the environment, so an unenforceable host, reused roles, or unconfined material stop the edge before it starts, with the report in the journal.
Refusals stop provisioning or the edge before it serves
A preflight refusal is a probe line at error severity and exit 1. A CLI refusal prints the standard four-line error to standard error (error[CODE]: message, then its help, code, and docs lines) and exits 1. Bearer-role refusals are on service roles.
| Refusal | Condition | Owner |
|---|---|---|
security. error: "the host lacks cage enforcement prerequisites: kernel 6.7 or newer, landlock abi 4 or newer, openat2 resolve flags", listing each one missing | A kernel feature is missing and --require- is set; without it, a warning | Preflight |
security. error: "the signed launch material authorizes the wrapped command at migration stage Disabled, which does not confine it" | Disabled or Shadow material under --require- | Preflight |
security. error: "the edge would refuse this launch: " and the loader's reason, such as an anchor that "shares the protected database snapshot domain" | The edge's loader refuses the material | Preflight |
"checking launch material needs --signed-manifest, --manifest- | Part of the launch material, before any probe; an unpaired flag fails parsing with exit 2 | Preflight |
"Enforced provisioning requires --receipt- | Enforced stage without the anchor flag; nothing created | Provisioning |
"receipt rollback anchor must be a directory", or under urn:chio:error:cli:io "failed to canonicalize receipt rollback anchor " with the path and system error | The anchor path is not a directory, or does not exist; nothing created | Provisioning |
"receipt rollback anchor must be an absolute canonical path", or "receipt rollback anchor must not contain symlinks, dot segments, or non-canonical components" | The anchor path is relative or not canonical | Provisioning |
"existing native MCP demo output is partial, tampered, or input- | Altered material, or material from other inputs | Provisioning |
"privileged discovery requires an Enforced cage; supply --tools-fixture for legacy provisioning" | Root with --discover-tools below Enforced | Provisioning |
Use a supported host, replace unconfined material with Enforced material, point the anchor flag at an existing canonical directory on its own device, and supply every signed input with the exact command. Preserve a mismatched directory and provision into a new one; deleting authority history or weakening preflight repairs nothing.
A unit stays activating or keeps restarting
Startup has not completed. Read the unit's journal and the authority it waits on, and keep traffic off the host until the unit reports active.
The broker lacks its authority although the units are ordered
An After= line orders units and supplies no authority. Restore and authenticate the authority the broker reads, then let Restart=on-failure retry the unit. Deployment observability covers restarts and ongoing health.
Provisioning and preflight reference
Search for anchor, discover-tools, native-runtime.json, or exit code.
Units and their start checks
| Unit | Runs | Checked before start |
|---|---|---|
chio- | Trust control plane | Preflight over its receipt, authority, and session stores |
chio- | MCP edge | Preflight with --require-; anchor mount /srv/ |
chio- | Secret broker | No preflight step |
chio- | One key-log witness per instance | No preflight step |
chio- | One key-log audit monitor per instance | No preflight step |
Probe severities
| Probe | Ok when | Info or warning when | Error when |
|---|---|---|---|
security. | The host meets every cage prerequisite | Warning: a prerequisite is missing | Missing, with --require- |
security. | Every set role is usable and distinct | Info: no role variable is set | A role is padded, empty, or has a control character; two roles share a value |
security. | The material authorizes the command under the cage | Info: no material given. Warning: authorizes without the cage | Without the cage under --require-, or the edge would refuse the launch |
security. | Every named store opens and passes quick_check | Info: none named, or a named store does not exist yet | A symlink or non-regular file, unopenable, or fails quick_check |
A captured platform-only report
chio security preflight
[ok] security.platform: the host satisfies every cage enforcement prerequisite
os: linux
arch: x86_64
kernel_release: 6.17.0-1020-oracle
landlock_abi: 7
nofile_soft: 1024
seccomp: yes
no_new_privs: yes
pidfd_open: yes
close_range: yes
execveat_empty_path: yes
sealed_memfd: yes
openat2: yes
statx_mount_id: yes
[info] security.bearer_roles: no bearer role is set in the environment, so role separation was not checked
help: export CHIO_AUTH_TOKEN, CHIO_ADMIN_TOKEN, CHIO_CONTROL_TOKEN and CHIO_REMOTE_AUTHORITY_WORKLOAD_TOKEN as the launch would
present:
[info] security.native_launch: no signed launch material was given, so the launch policy was not checked
help: pass --signed-manifest, --manifest-public-key, --cage-policy, --cage-policy-signer, --server-id and the wrapped command after --
[info] security.durable_stores: no durable store was named, so store health was not checked
help: pass --receipt-db, --session-db and --authority-db as the launch would
summary: worst severity = info, exit code = 0This is the complete standard output of the bare command with no bearer variable set, run with the chio built for x86_64-unknown-linux-gnu on Linux 6.17.0-1020-oracle x86_64. Standard error was empty and the command exited 0. The platform probe reported ok; the bearer-role probe, the first of three with nothing to check, set the worst severity to info. The context lines describe that host: kernel_release, landlock_abi, nofile_soft (the soft open-file limit), and each yes-or-no kernel feature. The report shows that the host met the cage prerequisites; it checked no role, launch, or store and confined nothing.
--stage
The migration stage provision-reference-runtime promotes its ledger to. Shadow material runs the launch without the cage; Enforced material is promoted through Shadow to Enforced.
--receipt-rollback-anchor-root
Names an existing directory on a persistent filesystem separate from the receipt database. Whenever the flag is given, at either stage, provisioning checks it before it creates anything. Rollback anchors explains what it protects.
Example/srv/chio-receipt-anchors/mcp-edge
--discover-tools
Spawns the target once, unconfined and as the calling user, and records its tools/list as reviewed-tools.json. Below the Enforced stage, discovery refuses to run as root. A Shadow provision needs no rollback anchor.
--tools-fixture
The reviewed reviewed-tools.json from the Shadow stage.
--cage-init, --read-path, --write-path
The material binds the static chio-cage-init, the target's digest, argument list, and working directory, and the read and write grants.
--require-enforcement
Turns a host or a launch that cannot confine into an error. --json prints the doctor JSON envelope instead of lines.
Probe inputs
The bearer-role probe reads CHIO_AUTH_TOKEN, CHIO_ADMIN_TOKEN, CHIO_CONTROL_TOKEN, and CHIO_REMOTE_AUTHORITY_WORKLOAD_TOKEN. The launch probe takes --signed-manifest, --manifest-public-key, --cage-policy, --cage-policy-signer, --server-id, and the wrapped command after --. The store probe takes the global options --receipt-db, --session-db, and --authority-db.
Exit code
0 for ok, info, or warning; 1 for error; 2 for fatal. cli/security_preflight.rs:141 exits with it, and the --json envelope carries the same number in exit_code.
native-runtime.json
Records the profile linux-x86_64-brokered-native-v1, the source commit, the Cargo.lock digest, and each executable's name, target, and SHA-256.
reference_runtime_units
Checks that each subcommand and flag a unit invokes exists, each credential is declared by systemd and consumed by the service, each account exists in sysusers.d, and each preflight step names what its service opens or launches.
Refusal sources
Platform: Prerequisite, doctor/security/platform.rs:58, rendered at :176. Unconfined launch: LaunchKind::LegacyAuthorized, doctor/security/launch.rs:118. Edge refusal, when the loader refuses the signed manifest, the launch policy, the wrapped command, or the server id: :132. Partial material: cli/security_preflight.rs:83; unpaired flags at :31-44. Anchor: provision/reference_runtime.rs:131 and :140-145, cli/mcp/provision.rs:1529-1541 and :1534. Mismatched output: cli/mcp/provision.rs:1885. Privileged discovery: discovery/launch.rs:47.
provision-native-mcp-demo
Writes the same kind of signed material at migration stage Disabled, for a host that serves without the cage: security mode disabled_legacy_authorized_demo, containmentEnforced false, and the warning "Disabled is legacy-authorized demo mode, not cage containment." It binds no read or write grant, uses the chio executable in place of a cage helper, and creates private signers for the demo only. Preflight reports its launch as a warning, which exits 0, and as an error under --require-enforcement.
chio security provision-native-mcp-demo \
--output-dir "$HOME/pricing-launch" \
--discover-tools \
--target /usr/local/libexec/chio/chio-tool-repo-reader \
--target-arg --root --target-arg "$HOME/pricing" \
--execution-uid "$(id -u)" --execution-gid "$(id -g)"