Chio/Docs

chio.yaml Configuration

chio.yaml tells a Chio runtime where its signing key lives, which upstream APIs to wrap, which protocol edges to expose, where to write receipts, and which WASM guard modules to load. The schema lives in chio-config, applies deny_unknown_fields everywhere, and runs environment variable interpolation on the raw text before parsing. This page is the field-level reference.


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 only always-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.

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.

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[]

Edges expose an adapter through a different protocol surface.

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.


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.
priorityu321000Lower values run first.
advisoryboolfalseWhen true, a failure is recorded but not blocking.

See Custom WASM Guards for the manifest format, signing, and the host-import surface.


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. To validate a config outside of a running process, 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 configuration validation 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-paths
    - 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) are wired through the policy compiler under the guards.cloud_guardrails and guards.threat_intel blocks of the HushSpec policy file, not in chio.yaml. See External Guards for that surface.


Next Steps

chio.yaml Configuration · Chio Docs