Chio/Docs

PlatformAuthoring

chio.yaml Configuration

A field reference for chio.yaml: runtime signing keys, upstream APIs, protocol endpoints, and guard modules.


Root Structure

The top-level object is ChioConfig with these sections:

FieldTypeRequiredDescription
kernelobjectYesSigning key, receipt store, kernel log level.
adaptersarrayYes (min 1)Upstream API connections.
edgesarrayNoProtocol edges (mcp, a2a) that expose adapters.
receiptsobjectNoReceipt store, retention, and checkpoint cadence.
loggingobjectNoLog level and output format.
telemetryobjectNoOpenTelemetry span export.
guardsobjectNoGlobally required guard names and advisory promotion.
wasm_guardsarrayNoWASM guard modules loaded at runtime.

kernel

The required section. It identifies the runtime to the rest of the system through its Ed25519 signing key.

FieldTypeDefaultNotes
signing_keystringrequiredHex-encoded Ed25519 key, or the literal "generate" for dev mode. Empty values are rejected.
receipt_storestring"sqlite:///var/chio/receipts.db"Receipt store URI used by the kernel directly.
log_levelstring"info"Kernel-subsystem log level. The top-level logging.level covers the rest of the runtime.
deadlinesobjectkernel defaultsHot-path wall-clock budgets. Optional; an absent table falls back to kernel defaults. See below.

signing_key: generate is not for production

"generate" creates an ephemeral keypair at startup. Receipts signed by an ephemeral key are unverifiable after restart. Use a persistent hex-encoded key in any deployment that has to survive a restart.

kernel.deadlines

An optional sub-section exposing the runtime hot-path wall-clock budgets. Only the scalar budgets are set from the file; the per-guard and per-server override maps are wired programmatically. Every field is optional, so an absent kernel.deadlines table is valid — each Some value replaces the matching kernel default and each omitted field keeps it. The section applies deny_unknown_fields.

FieldTypeNotes
guard_pipeline_budget_msu64 (optional)Wall-clock budget for the full guard pipeline.
dispatch_budget_msu64 (optional)Budget for dispatch to the tool server.
receipt_append_budget_msu64 (optional)Budget for appending a receipt.
receipt_writer_poll_msu64 (optional)Receipt-writer poll interval.
receipt_writer_stall_msu64 (optional)Threshold before the receipt writer is treated as stalled.

adapters[]

Each adapter connects the kernel to one upstream API. At least one adapter is required.

FieldTypeRequiredNotes
idstringYesUnique within the file. Referenced by edges.
protocolstringYesAdapter type: openapi, grpc, graphql, etc.
upstreamstringYesURL of the upstream API.
specstringNoPath to a spec file (for openapi, the OpenAPI YAML/JSON).
authobjectNoUpstream authentication.

auth

yaml
auth:
  type: bearer        # one of: bearer, api_key, cookie, mtls, none
  header: Authorization  # required for bearer and api_key

Validation:

  • type must be one of bearer, api_key, cookie, mtls, none.
  • When type is bearer or api_key, the header field is required.
  • cookie, mtls, and none may omit header.

edges[]

Each edge exposes an adapter through a protocol endpoint.

FieldTypeNotes
idstringUnique within the file.
protocolstringEdge protocol: mcp, a2a, acp, etc.
expose_fromstringAdapter id that this edge surfaces. Must reference a declared adapter.

receipts

FieldTypeDefaultNotes
storestring"sqlite:///var/chio/receipts.db"Receipt store URI.
checkpoint_intervalu64100Receipts between Merkle checkpoints. 0 disables.
retention_daysu6490Days to retain receipts before expiry.

logging

FieldTypeDefaultAllowed values
levelstring"info"trace, debug, info, warn, error
formatstring"json"json, text

telemetry

FieldTypeDefaultNotes
enabledboolfalseMaster switch for OTel export.
endpointstring""OTel collector URL (e.g., http://localhost:4317).
service_namestring"chio-acp-proxy"Service identifier reported to the collector.
include_parametersboolfalseInclude receipt parameters in span attributes. Off by default to avoid leaking sensitive data.
batch_sizeusize0Span batch size. 0 exports each span immediately.

guards

Globally applied guard configuration. Per-guard configuration (forbidden paths, tool access, egress) belongs in a HushSpec policy; this section sets pipeline-wide knobs.

FieldTypeDefaultNotes
allow_advisory_promotionboolfalseWhen true, advisory-only verdicts can be promoted to deterministic blocking via overlay.
requiredstring[][]Guard names that must pass on every request, regardless of route.

For details on which guards are configurable through HushSpec, see HushSpec Policy Format. For the runtime pipeline, see Default Pipeline.

Additional guard configuration

The two fields above are the thin base-runtime schema. A separate, guard-crate-level tuning also lives under guards — per-guard blocks such as internal_network.extra_blocked_hosts, agent_velocity.max_requests_per_agent, data_flow, behavioral_sequence, response_sanitization.min_level/action, and the advisory knobs (anomaly, data-transfer, promotion rules). These configure individual individual guards. Each guard's reference page documents its own block — see, for example, Network Guards for internal_network and Filesystem Guards for the path guards.

wasm_guards[]

Each entry registers a WASM guard module for the pipeline. The loader walks up from path to read guard-manifest.yaml from the same directory.

FieldTypeDefaultNotes
namestringrequiredSurfaces in receipts and logs.
pathstringrequiredFilesystem path to the .wasm module.
fuel_limitu6410000000Max fuel units per invocation.
priorityu321000Intended to order evaluation (lower = earlier) and validated as such by chio-config, but the kernel's guard registration path does not currently sort by priority. Insertion order — the order wasm_guards[] entries appear in the file — determines actual evaluation order. Order your entries accordingly.
advisoryboolfalseWhen true, a failure is recorded but not blocking.

See Custom WASM Guards for the manifest format, signing, and host imports.


Environment Variable Interpolation

Interpolation runs on the raw YAML before parsing, so every string-typed field is eligible. Two patterns are supported:

text
${VAR}            # required: error if VAR is unset
${VAR:-default}   # optional: use VAR if set, otherwise the default literal

Variable names match [A-Za-z_][A-Za-z0-9_]*. If multiple required variables are unset, the loader reports them all in a single error so you can fix everything in one pass. The sequence $​{} with no variable name is left as literal text.

yaml
kernel:
  signing_key: "${CHIO_SIGNING_KEY}"
  log_level: "${CHIO_LOG_LEVEL:-info}"

adapters:
  - id: petstore
    protocol: openapi
    upstream: "http://${API_HOST}:${API_PORT:-8080}/api"
    auth:
      type: bearer
      header: Authorization

Validation

Validation runs after interpolation and YAML deserialization. All errors collect into a single ConfigError::Validation so the operator can fix everything at once.

  • deny_unknown_fields. Every section rejects unknown keys at parse time. Typos like recieipts fail before validation runs.
  • At least one adapter. An empty adapter list is rejected.
  • Unique adapter IDs. Duplicates are rejected by string comparison. Empty IDs are also rejected.
  • Unique edge IDs. Same rule. Empty edge IDs are rejected.
  • Reference integrity. Every edge.expose_from must match an adapter id declared in the same file.
  • Auth completeness. type values are enumerated; bearer and api_key require a header.
  • Non-empty signing key. kernel.signing_key must not be the empty string.
  • Logging enums. level and format are checked against their fixed value sets.

Loading from Code

Programmatic callers use the loader entry points in chio-config:

rust
use chio_config::{load_from_file, load_from_str, ChioConfig};

// From a file path:
let config: ChioConfig = load_from_file(Path::new("/etc/chio/chio.yaml"))?;

// From a string (e.g., loaded over the network):
let config: ChioConfig = load_from_str(yaml_text)?;

Both helpers run interpolation, parse with deny_unknown_fields, and run the validation pass before returning. Errors are surfaced as ConfigError with Io, Interpolation, Parse, and Validation variants.

No universal chio start command

The Chio CLI does not ship a single chio start --config chio.yaml entry point. Individual subcommands and embedded runtimes that consume chio.yaml opt in through their own flags or programmatic APIs. The CLI does ship a chio doctor probe that parses chio.yaml and checks a minimal marker schema — the top-level version and policy keys, not the adapter/edge runtime schema on this page (see below). For the full runtime schema, call chio_config::load_from_file from a small Rust binary or a test harness.

CLI Policy Checks

The chio CLI exposes commands for evaluating policies (a separate file from chio.yaml) but does not offer a top-level chio config validate subcommand today. The policy-facing commands are:

bash
# Spawn an agent under a HushSpec policy.
$ chio run --policy ./policy.yaml -- agent --task my-task

# Evaluate a single tool call against a policy without spawning anything.
$ chio check --policy ./policy.yaml \
    --tool read_file \
    --params '{"path": "/etc/passwd"}' \
    --server '*'

# Scaffold a new project with a sample chio.yaml and policy.
$ chio init my-deployment

For a CLI-level check, chio doctor runs six ordered health probes; the sixth parses chio.yaml and checks for two top-level marker keys, version and policy, reporting errors with line and column anchors. chio doctor --fix scaffolds a minimal file containing exactly those keys (version: 1, policy: ./policy.yaml).

The doctor probe validates a different, minimal schema

The probe's version/policy marker schema is a separate contract from the kernel/adapters/edges runtime schema this page documents. A well-formed adapter/edge chio.yaml carries neither version nor policy and does not satisfy the probe. For full validation of the runtime schema in CI, write a small Rust test that calls load_from_file and asserts Ok, or shell out from a build script.

Worked Example

A complete chio.yaml for a small deployment: one MCP edge over an OpenAPI adapter, one external guard reachable via the policy compiler, and one custom WASM guard. Secrets are interpolated from the environment.

chio.yaml
kernel:
  signing_key: "${CHIO_SIGNING_KEY}"
  receipt_store: "sqlite:///var/lib/chio/receipts.db"
  log_level: "${CHIO_KERNEL_LOG_LEVEL:-info}"

adapters:
  - id: petstore
    protocol: openapi
    upstream: "https://${PETSTORE_HOST}/v1"
    spec: ./specs/petstore.openapi.yaml
    auth:
      type: bearer
      header: Authorization

edges:
  - id: petstore-mcp
    protocol: mcp
    expose_from: petstore

receipts:
  store: "sqlite:///var/lib/chio/receipts.db"
  checkpoint_interval: 200
  retention_days: 365

logging:
  level: "${CHIO_LOG_LEVEL:-info}"
  format: json

telemetry:
  enabled: true
  endpoint: "http://${OTEL_HOST:-localhost}:4317"
  service_name: chio-petstore-edge
  include_parameters: false
  batch_size: 100

guards:
  required:
    - forbidden-path
    - secret-leak
    - patch-integrity
  allow_advisory_promotion: false

wasm_guards:
  - name: tool-denylist
    path: /etc/chio/guards/tool-denylist/tool_denylist_guard.wasm
    fuel_limit: 5000000
    priority: 100

  - name: org-pii-scanner
    path: /etc/chio/guards/pii-scanner/pii_guard.wasm
    fuel_limit: 20000000
    priority: 200
    advisory: false

External provider guards (Bedrock, Azure, Vertex, Safe Browsing, VirusTotal, Snyk) use a distinct policy schema. They are not configured through chio.yaml or a guards: block inside a HushSpec document. Their cloud-guardrail and threat-intel configuration lives on the control-plane external-guard policy schema (the cloud_guardrails and threat_intel fields on GuardPolicyConfig), which the control plane compiles into a pipeline via build_guard_pipeline and build_post_invocation_pipeline (re-exported from chio_control_plane::policy). Within a HushSpec document, threat-intel-driven detection is instead configured at extensions.detection.threat_intel (compiling to the EmbeddingAnomalyGuard). See External Guards for that schema.


Next Steps