Deployment hardening
Close bypass routes, separate service identities, protect durable state, and verify the chosen execution profile before serving agent traffic.
On this page
A hardened deployment makes the governed path the only reachable path. Every tool and effect path on the host is inventoried, each service runs under its own identity, the stores that hold authority are protected, the confined launch is admitted by enforcement-required preflight, and readiness waits until every authority answers.
Chio supplies the policy, authority, information-flow, confinement, custody, and recovery mechanisms; the deployment connects them through authenticated hosts, independent services, private storage, and readiness checks. For every path, keep one ordinary useful operation and its closest forbidden variation, and observe the protected resource independently of the verdict.
StartThe host closes the route the kernel never sees
The host decides which processes run, which credentials and handles they receive, and which adapters can reach protected resources. A governed server intercepts only the calls that reach it. Security threat model.
- 7unmediated route no check. A second route to the resource, such as a writable mount, an inherited credential, or a separate native tool, is outside both the control and the record. Close it to make admission mandatory.
1. Inventory every effect path
An agent with a narrow declared tool set can still sit on a host with broad filesystem access, direct provider credentials, or a second execution service. List the agent host's built-in shell, filesystem, browser, network, and MCP tools, then its direct provider SDKs, credential files, inherited environment variables, local sockets, and delegated executors. A governed connector mediates only its own path; the host closes every other route on this list.
Pair each tool's ordinary operation with the nearest one that must be refused: the workspace reader returns src/pricing.py but not /secrets/.env; the shell tool runs the pricing tests but not curl to collect.example.net; the brokered issue tool opens issue #419 on the pricing repository but not on another account. Follow the ordinary operation to its resource and record the authenticated host, capability issuer, policy owner, executor, durable stores, and output destination, plus the credential service and its hold connection for brokered work, and the authority snapshot and control adapters for active response.
| Resource | Inspect on the running host | Negative case |
|---|---|---|
| Project filesystem | Granted roots and retained descriptors | Read or write outside the task's roots |
| Provider account | Broker adapter, credential reference, destination commitment | Change the destination, keep the old authority |
| Private service socket | Directory ownership and authenticated peer | Connect as another process or swap the endpoint |
| Durable store | Service-private path, owner, recovery contract | Start with missing or inconsistent state |
| Response control | Authorized target and per-response contribution | Remove one response while another applies |
You should have, for each tool, a composition from security profiles and an operation pair with an observable result. Note what each receiving process can change and which upstream check it relies on; an adapter trusting a caller-selected tenant, or a recovery path rebuilding an unchecked destination, shows up here. Unsupported declarations and incomplete authority bundles refuse startup before any launch or provider authority is acquired.
2. Run each service under its own identity
Each reference-runtime service family runs under its own account and credential. Unit ordering enforces one dependency across families: the remote MCP edge hard-requires the trust control plane. The broker's authority connection, and the trust control plane's keyring readiness when an operator configures a keyring, fail their own startup until the dependency answers, and systemd retries under Restart=on-failure. Service roles gives the accounts, bearer roles, and start order.
3. Protect the stores that hold authority
List every store that holds authority. Whenever a receipt store or finding-pool ledger has an anchor root configured, keep that rollback anchor on a device separate from its database, and rehearse a restore before you need one. Protect durable state covers the stores, anchors, archive, and rehearsal.
4. Admit the confined launch with enforcement-required preflight
Confined native tools run under the Linux enforcement profile: Landlock, seccomp, descriptor identity, and the observed exec transition. On the provisioned Linux x86_64 host, admit the exact installed signed launch as the chio-edge identity, with the anchor mount, public pins, and launch files from the reference runtime:
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 every probe at ok and exit code 0. Then run the pair: a read of src/pricing.py succeeds, and a read of /secrets/.env outside the root is refused without touching that file. Preflight admits the launch, and only the observed pair shows the boundary; a role-only report, a portable test, or an unrelated startup failure proves nothing about that pair. Linux confinement covers the kernel requirements, the cage suite, and how to read a refusal.
5. Publish the host only when its authorities answer
A service is ready when its authorities are healthy and its retained work is reconciled enough to serve. Start the dependencies, authenticate their identities, verify their stores and policy, drain durable recovery, and only then publish the host to traffic. A missing authority, unresolved release custody, failed peer verification, or exhausted recovery bound holds readiness back. A kernel restarted under a durable emergency stop reports ready_stopped and keeps refusing.
Define the effect of each required service's outage on new work and on retained operations. Once a tool is enforced, an operational failure keeps the enforced route and refuses; the host never falls back to direct execution, because a fallback would remove the protection exactly when the deployment is under stress.
6. Retain the deployment acceptance evidence
Record the exact host and runtime, the tool inventory, credentials, service peers, resource grants, manifests, policy hashes, and recovery state. Finish with the permitted operation and its nearest refused variation on the deployed host, each with its receipt and an independent observation of the resource.
You should hold a record that ties every claim to the installed composition. Two commands add the product's own evidence to it: the enforcement suites run against the installed binaries on this host, and the release check shows that the release you run passed its qualification gates before it was tagged.
chio security selftest cage restart --require-all --evidence ./deployment-evidence
chio release verify --evidence qualificationsuite result cage pass Linux enforcement: namespaces, seccomp, Landlock, cgroup v2 restart pass every required case passed once; inventory complete 2 suites passed; evidence in ./deployment-evidence binary /usr/local/bin/chio chio 0.2.0 x86_64-unknown-linux-gnu checksum matches SHA256SUMS for v0.2.0 signed by release.yml on backbay-labs/chio, issuer token.actions.githubusercontent.com provenance SLSA v1, 5 subjects, tag v0.2.0 qualification summary bound to v0.2.0 security-dependencies pass cage-enforcement pass native-restart-safety pass verified
--require-all turns a suite the host cannot run into exit 2, so a host without the Linux mechanisms cannot pass this step by skipping the cage. ./deployment-evidence keeps every suite log, its exit status, and a SHA-256 manifest. The release check verifies the qualification summary the release workflow signed and attached to the tag, including the dependency audit, which runs only on the release builders.
Change one bypass route at a time
After the useful control passes, vary only the boundary under review: the same executable and request with the forbidden filesystem root, or the same credential request with a new destination. Inspect the file or provider independently of the verdict. An application can return Deny after leaking a file, and the independent observation is what catches that regression.
Repeat the inventory whenever a shell, browser, direct SDK, credential mount, delegated executor, or network path is added, even with the kernel binary unchanged. Bypass resistance supplies the application controls; shadow migration and rolling out active defense move response from shadow to enforcement.
A refusal counts only when it isolates the boundary
A refusal caused by an unrelated broken prerequisite proves nothing about the boundary under review: if the provider account is unreachable, the refused-destination case has not isolated destination authorization. Establish the useful control first, then change one property while the rest of the composition stays valid.
The cage suite reports skipped
The host lacks a Linux mechanism the cage needs, and --require-all exits 2. Run the suite on the host that will launch the tool; a --portable run checks host-independent cases and is never recorded as enforcement evidence.
The release check refuses
A release:signature-invalid or release:provenance-mismatch error means the installed binary is not the release it claims to be. Reinstall from the signed release before serving traffic.
The cage or restart suite fails
The installed composition has an unresolved covered boundary on this host. Keep the evidence directory and the release version, and repair that defect. For an absent authority, repair its identity, health, and durable recovery before readiness; for an unsupported physical profile, select a supported host; for a resource-boundary failure, repair the enforcing route and close any alternate one.
When both suites pass and the useful neighbor passes, the suites' resource oracles observed their covered Linux boundary on this host; retain the evidence and test the deployed pair. Once the host serves, investigate a session covers incidents.