Chio/Docs
LOGIN · JOIN

chio.yaml Configuration

Find a chio.yaml field, its default, and the validation rule the loader applies before the kernel starts.

Reference chio@5f63e6e

On this page

chio.yaml configures the process that hosts the kernel: its signing key, the upstream adapters, the protocol edges that expose them, receipt storage, logging, telemetry, and guard loading. Policy lives in a separate HushSpec document. The policy decides what a request may do; chio.yaml decides which identity, transports, and stores the process uses.

The file below is a complete configuration for the pricing service: one MCP edge over an OpenAPI adapter for its quote, discount, and refund operations, with two WASM guards. Secrets come from the environment through interpolation.

A complete file

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

adapters:
  - id: pricing
    protocol: openapi
    upstream: "https://${PRICING_HOST}"
    spec: ./openapi.yaml
    auth:
      type: bearer
      header: Authorization

edges:
  - id: pricing-mcp
    protocol: mcp
    expose_from: pricing

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-pricing-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: customer-pii-scanner
    path: /etc/chio/guards/customer-pii-scanner/pii_guard.wasm
    fuel_limit: 20000000
    priority: 200
    advisory: false

Each node receives this file as a local file. Policy Rollout covers how the same bytes reach every node and how to detect two nodes that hold different bytes.

Top-level sections

The top-level object is ChioConfig. Only kernel and adapters are required.

FieldTypeRequiredHolds
kernel
object
Yes
Signing key, receipt store, kernel log level.
adapters
array
Yes (min 1)
Upstream API connections.
edges
array
No
Protocol edges (mcp, a2a) that expose adapters.
receipts
object
No
Receipt store, retention, and checkpoint cadence.
logging
object
No
Log level and output format.
telemetry
object
No
OpenTelemetry span export.
guards
object
No
Globally required guard names and advisory promotion.
wasm_guards
array
No
WASM guard modules loaded at runtime.

kernel

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

signing_key

stringRequired

A hex-encoded Ed25519 key, or the literal "generate" for development. The empty string is rejected. "generate" creates an ephemeral keypair at startup, so receipts it signs are unverifiable after a restart; a deployment that must survive a restart uses a persistent hex key.

Example"${CHIO_SIGNING_KEY}"

receipt_store

stringDefault: "sqlite:///var/chio/receipts.db"

The receipt store URI the kernel writes to directly.

Example"sqlite:///var/lib/chio/receipts.db"

log_level

stringDefault: "info"

The kernel subsystem's log level. The top-level logging.level covers the rest of the runtime.

Example"${CHIO_KERNEL_LOG_LEVEL:-info}"

deadlines

objectOptional

Hot-path wall-clock budgets. An absent table keeps the kernel defaults. The fields are listed under kernel.deadlines.

kernel.deadlines

The file sets the scalar budgets; the per-guard and per-server override maps are set programmatically. Every field is optional. Each value present replaces the matching kernel default, and each omitted field keeps it. The section applies deny_unknown_fields.

FieldTypeBudget for
guard_pipeline_budget_ms
u64 (optional)
The full guard pipeline.
dispatch_budget_ms
u64 (optional)
Dispatch to the tool server.
receipt_append_budget_ms
u64 (optional)
Appending one receipt.
receipt_writer_poll_ms
u64 (optional)
The receipt writer's poll interval.
receipt_writer_stall_ms
u64 (optional)
Time before the receipt writer counts as stalled.

adapters[]

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

FieldTypeRequiredNotes
id
string
Yes
Unique within the file. Referenced by edges.
protocol
string
Yes
Adapter type: openapi, grpc, graphql, and others.
upstream
string
Yes
URL of the upstream API.
spec
string
No
Path to a spec file; for openapi, the OpenAPI YAML or JSON.
auth
object
No
Upstream authentication.

adapters[].auth

chio.yaml · adapters[].authyaml
auth:
  type: bearer        # one of: bearer, api_key, cookie, mtls, none
  header: Authorization  # required for bearer and api_key
  • type is one of bearer, api_key, cookie, mtls, none.
  • bearer and api_key require header.
  • cookie, mtls, and none may omit header.

edges[]

Each edge exposes one adapter through a protocol endpoint.

FieldTypeNotes
id
string
Unique within the file.
protocol
string
Edge protocol: mcp, a2a, acp, and others.
expose_from
string
The id of a declared adapter this edge surfaces.

receipts

FieldTypeDefaultNotes
store
string
"sqlite:///var/chio/receipts.db"
Receipt store URI.
checkpoint_interval
u64
100
Receipts between Merkle checkpoints. 0 disables checkpoints.
retention_days
u64
90
Days to retain receipts before expiry.

logging

FieldTypeDefaultAllowed values
level
string
"info"
trace, debug, info, warn, error
format
string
"json"
json, text

telemetry

FieldTypeDefaultNotes
enabled
bool
false
Master switch for OpenTelemetry export.
endpoint
string
""
Collector URL, such as http://localhost:4317.
service_name
string
"chio-acp-proxy"
Service identifier reported to the collector.
include_parameters
bool
false
Copies receipt parameters into span attributes; off keeps sensitive arguments out of spans.
batch_size
usize
0
Span batch size. 0 exports each span immediately.

guards

Pipeline-wide guard settings. Per-guard rules such as forbidden paths, tool access, and egress belong in a HushSpec policy; the runtime order is on Default Pipelines.

FieldTypeDefaultNotes
allow_advisory_promotion
bool
false
true lets an overlay promote advisory verdicts to blocking.
required
string[]
[]
Guard names that must pass on every request, on every route.

Those two fields are the base runtime schema. Guard crates read their own tuning blocks under guards: internal_network.extra_blocked_hosts, agent_velocity.max_requests_per_agent, data_flow, behavioral_sequence, response_sanitization.min_level and action, and the advisory settings for anomaly, data transfer, and promotion rules. Each guard's page documents its block, for example Network Guards for internal_network and Filesystem Guards for the path guards.

External provider guards (Bedrock, Azure, Vertex, Safe Browsing, VirusTotal, Snyk) are configured on the control plane's external-guard policy schema: the cloud_guardrails and threat_intel fields on GuardPolicyConfig. The control plane compiles them into pipelines with build_guard_pipeline and build_post_invocation_pipeline, re-exported from chio_control_plane::policy. Inside a HushSpec document, threat-intel detection sits at extensions.detection.threat_intel and compiles to the EmbeddingAnomalyGuard. External Guards documents that schema.

wasm_guards[]

Each entry declares one WASM guard module for the pipeline. The loader reads the module's guard-manifest.yaml from the directory that holds the path file. Custom WASM Guards covers the manifest format, signing, and host imports.

FieldTypeDefaultNotes
name
string
required
Appears in receipts and logs.
path
string
required
Filesystem path to the .wasm module.
fuel_limit
u64
10000000
Maximum fuel units per invocation.
priority
u32
1000
Evaluation order: lower values run first; ties break on advisory.
advisory
bool
false
true records a failure without blocking.

Environment variable interpolation

Interpolation runs on the raw YAML before parsing, so every string-typed field can take a variable. Two patterns are recognized.

Interpolation patternstext
${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_]*. When several required variables are unset, the loader names all of them in one error. The sequence $​{} with no variable name stays literal text.

chio.yaml · interpolated fieldsyaml
kernel:
  signing_key: "${CHIO_SIGNING_KEY}"
  log_level: "${CHIO_LOG_LEVEL:-info}"

adapters:
  - id: pricing
    protocol: openapi
    upstream: "http://${PRICING_HOST:-127.0.0.1}:${PRICING_PORT:-9440}"
    auth:
      type: bearer
      header: Authorization

Validation rules

Validation runs after interpolation and deserialization. Every failure collects into one ConfigError::Validation, so one run reports all of them.

  • Unknown keys. Every section applies deny_unknown_fields, so a typo such as recieipts fails at parse time, before validation.
  • At least one adapter. An empty adapter list is rejected.
  • Unique adapter ids. Duplicates are rejected by string comparison, and so are empty ids.
  • Unique edge ids. The same rule, including empty ids.
  • Reference integrity. Every edge.expose_from matches an adapter id declared in the same file.
  • Auth completeness. type takes an enumerated value; bearer and api_key require a header.
  • Signing key present. kernel.signing_key is a non-empty string.
  • Logging values. level and format take values from their fixed sets.

Loading from Rust

Programs that embed the kernel load the file through the chio-config crate.

src/main.rs · embedding the kernelrust
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 functions interpolate, parse with deny_unknown_fields, and validate before returning. Failures arrive as ConfigError with the variants Io, Interpolation, Parse, and Validation. A CI check for the runtime schema is a small Rust test that calls load_from_file and asserts Ok.

chio start runs the sidecar with zero-config defaults and takes no --config flag. Subcommands and embedded runtimes that read chio.yaml opt in through their own flags or programmatic APIs.

CLI checks

A policy is a separate file from chio.yaml, and the CLI evaluates it with its own commands.

Terminalbash
# Spawn an agent under a HushSpec policy.
$ chio run --policy ./policy.yaml -- python agent.py --issue 416

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

# Scaffold a new project with a sample chio.yaml and policy.
$ chio init pricing

chio doctor runs six ordered health probes. The sixth parses chio.yaml, checks the two top-level marker keys version and policy, and reports errors with line and column anchors. chio doctor --fix scaffolds a minimal file with exactly those keys: version: 1 and policy: ./policy.yaml. The marker schema is its own contract; the kernel, adapters, and edges schema above is validated by chio_config::load_from_file.

Next: write the policy that pairs with chio.yaml

chio.yaml Configuration · Chio Docs