ReferenceSpec
HTTP Transport
The HTTP sidecar protocol, version 1.0: the /chio routes, ChioHttpRequest, Verdict, HttpReceipt, and the conversion to ChioReceipt, as chio-http-core implements them.
Source
This page normatively reflects spec/HTTP-SUBSTRATE.md in the chio repository. Status: Normative. Version 1.0. The keywords MUST, SHOULD, and MAY are normative per RFC 2119.
Where that document and the code differ, the page follows the crate crates/platform/chio-http-core (evaluation.rs, verdict.rs, receipt.rs) and the sidecar in crates/products/chio-api-protect/src/proxy, which are the normative source for wire behavior.
Synopsis
POST /chio/evaluate body: ChioHttpRequest -> 200 EvaluateResponse { verdict, receipt, evidence, execution_nonce? }
POST /chio/verify body: HttpReceipt -> 200 VerifyReceiptResponse
GET /chio/live -> 200 HealthResponse { status, version, receipt_backend, revocation_backend }
GET /chio/health -> 200 | 503 HealthResponseThe routes chio-api-protect mounts under /chio, with the request and response types chio-http-core defines.
Overview
A Chio kernel runs as a local process and exposes an HTTP API on localhost. Framework middleware or an SDK intercepts an incoming HTTP request, constructs a ChioHttpRequest, sends it to the sidecar, and enforces the returned verdict. The same types serve the chio api protect reverse proxy, which evaluates the request in-process and forwards it itself.
Sidecar evaluation protocol
Transport
The sidecar MUST listen on 127.0.0.1:9090 by default; that is the default of the --listen flag of chio api protect. Implementations MAY override the sidecar URL via:
- An explicit configuration value (
sidecarUrlin SDK config, or equivalent) - The
CHIO_SIDECAR_URLenvironment variable
If both are set, the explicit configuration value takes precedence. If neither is set, the default http://127.0.0.1:9090 MUST be used. All request and response bodies MUST use Content-Type: application/json.
Endpoints
| Endpoint | Method | Purpose |
|---|---|---|
/chio/evaluate | POST | Evaluate an HTTP request against policy and sign a receipt |
/chio/verify | POST | Verify a receipt: signature, content-addressed id, and authority semantics |
/chio/live | GET | Process liveness; answers 200 while the process runs |
/chio/health | GET | Dependency-aware readiness and the storage backends in effect |
The sidecar also mounts the approval routes under /approvals and the SDK helper routes under /v1, behind the sidecar-control token where noted in crates/products/chio-api-protect/src/proxy/router.rs. Those routes are outside this protocol.
POST /chio/evaluate
Evaluates an HTTP request against the loaded policy and returns a signed receipt. The sidecar reads at most 10 MiB of request body, decodes it as a ChioHttpRequest, and records the receipt before answering.
Request body: ChioHttpRequest.
Response body: EvaluateResponse.
| Field | Type | Required | Description |
|---|---|---|---|
verdict | Verdict | MUST | The evaluation verdict |
receipt | HttpReceipt | MUST | Signed receipt that records the evaluation |
evidence | GuardEvidence[] | MUST | Guard evidence collected during evaluation. Always serialized; a decoder treats an absent field as []. |
execution_nonce | SignedExecutionNonce or absent | MAY | Present only when the kernel issues one: an allow verdict from a kernel configured with an execution nonce. The client MUST re-present it as ToolCallRequest.execution_nonce before the governed action executes. In strict mode the preflight response carries incomplete plus this field, and the caller retries with the nonce. Absent on deny and cancel, on deployments without a nonce config, and on advisory routes. |
Status codes:
200 OK. Evaluation completed, for every verdict, including a deny for a revoked capability. Theverdictfield carries the outcome.400 Bad Request,"error": "chio_bad_request". The body could not be read or does not decode as aChioHttpRequest.409 Conflict,"error": "chio_approval_required". The route is approval-gated and the decision is pending; the body carrieskernel_receipt_idand, when the sidecar holds an approval handle,approval_idandresume_path.500 Internal Server Error,"error": "chio_evaluation_failed"for any other evaluation error, or"error": "chio_receipt_persistence_failed"when the receipt could not be recorded.
Status 200 for every verdict
verdict field.POST /chio/verify
Verifies the signature, content-addressed id, and authority semantics of a previously issued HttpReceipt. The sidecar reads at most 1 MiB of body and answers 400 chio_bad_request when the body does not decode as an HttpReceipt.
Request body: HttpReceipt.
Response body: VerifyReceiptResponse. There is no single valid field; the response decomposes verification into these fields:
| Field | Type | Description |
|---|---|---|
signature_valid | boolean | HttpReceipt::verify_signature: the authority semantics hold, the recomputed id matches, and the signature verifies against kernel_key |
signer_trusted | boolean | Whether kernel_key equals the public key of the sidecar's own signer |
receipt_id_valid | boolean | Whether id matches the recomputed content-addressed id |
parameter_hash_valid | boolean | Whether content_hash is a well-formed 64-character lowercase hex digest |
receipt_kind | string | The receipt's receipt_kind as a string |
boundary_class | string | The receipt's boundary_class as a string |
trust_level | string | The receipt's trust_level as a string |
result | string | Verdict result: allow, deny, cancelled, or incomplete |
authorized | boolean | ok and the verdict is allow. Gate execution on this field. |
signer_key_hex | string | Hex encoding of kernel_key |
ok | boolean | Roll-up: signature valid, signer trusted, id valid, parameter hash valid, and the semantics are mediated_decision, prevent, no observation_outcome, mediated |
No field reads timestamp. A receipt with a valid signature but an expired timestamp still reports signature_valid: true; temporal validity is the caller's responsibility.
GET /chio/live and GET /chio/health
Both routes answer with a HealthResponse. Liveness is process-only: it reports healthy and empty backend fields while the process runs, so a dependency fault does not restart a container that is serving. Readiness consults the proxy state.
| Field | Type | Required | Description |
|---|---|---|---|
status | string | MUST | One of "healthy", "degraded", or "unhealthy" |
version | string | MUST | The chio-api-protect package version |
receipt_backend | string | MUST | Backend of the embedded kernel's receipt log: durable or ephemeral. Empty on /chio/live; a decoder treats an absent field as empty. |
revocation_backend | string | MUST | Backend of the embedded kernel's revocation state: durable, remote, or ephemeral. Empty on /chio/live. |
Status codes on /chio/health: 200 OK when healthy; 503 Service Unavailable when degraded or unhealthy. The sidecar reports unhealthy when its durable receipt store is no longer reachable, because every mediated call would then be denied fail closed.
Timeout and failure behavior
SDKs MUST implement a configurable timeout for sidecar calls. The default timeout SHOULD be 5000 milliseconds; the TypeScript node-http package defaults timeoutMs to 5000.
Fail-closed by default
Sequence
spec/HTTP-SUBSTRATE.md:133-152at fe56570spec/HTTP-SUBSTRATE.md:154-162at fe56570ChioHttpRequest
The protocol-agnostic HTTP request that Chio evaluates. It is the shared input type for every HTTP adapter: reverse proxy, framework middleware, and sidecar alike. The fields in this table are the ones the specification defines.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
request_id | string | MUST | Unique request identifier. UUIDv7 recommended; the proxy mints one with Uuid::now_v7. | |
method | HttpMethod | MUST | HTTP method of the request | |
route_pattern | string | MUST | Matched route pattern (e.g., "/pets/{petId}"). The sidecar re-matches path against its own route table and ignores the client's value. | |
path | string | MUST | Actual request path (e.g., "/pets/42") | |
query | map<string, string> | MAY | {} | Query parameters. Omitted from the wire when empty. |
headers | map<string, string> | MAY | {} | Selected headers. Adapters MUST NOT include raw auth credential headers. |
caller | CallerIdentity | MUST | Extracted caller identity | |
body_hash | string or null | MAY | null | SHA-256 hex hash of the request body. null for bodyless requests (GET, HEAD, OPTIONS). |
body_length | integer | MAY | 0 | Content-Length of the request body in bytes |
session_id | string or null | MAY | null | Session ID this request belongs to |
capability_id | string or null | MAY | null | Capability token ID presented with this request |
timestamp | integer | MUST | Unix timestamp (seconds) when the request was received |
Sidecar-only fields
The crate carries further optional fields that the schema file does not list. Each is omitted from the wire when absent.
| Field | Type | Description |
|---|---|---|
tool_server | string or null | Tool server identity for a synthetic sidecar evaluation of a governed action |
tool_name | string or null | Tool name for a synthetic sidecar evaluation |
arguments | object or null | Structured arguments for a synthetic sidecar evaluation |
model_metadata | ModelMetadata or null | Model identity and safety tier for model-constrained grants |
governed_intent, approval_token, approval_tokens, threshold_approval_proposal, supplemental_authorization | any or null | Authorization extensions the HTTP authority does not enforce. A request that carries one is denied at the authority boundary instead of being silently ignored. |
execution_nonce | SignedExecutionNonce or null | The signed nonce presented to complete a strict nonce preflight |
Content hash computation
The content hash that binds a request to its receipt is computed as the SHA-256 hex digest of the canonical JSON (RFC 8785) of the following binding object, which ChioHttpRequest::content_hash serializes from the RequestContentBinding struct:
{
"body_hash": "<body_hash or null>",
"method": "<HTTP method>",
"path": "<actual path>",
"query": { "<sorted query params>" },
"route_pattern": "<route pattern>"
}CallerIdentity
The identity of the caller as extracted from the HTTP request.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
subject | string | MUST | Stable identifier for the caller | |
auth_method | AuthMethod | MUST | How the caller authenticated | |
verified | boolean | MAY | false | Whether this identity has been cryptographically verified. The proxy sets false for every identity it extracts. |
tenant | string or null | MAY | null | Tenant or organization the caller belongs to |
agent_id | string or null | MAY | null | Agent identifier when the caller is an AI agent |
Identity hash: the caller_identity_hash in receipts is the SHA-256 hex digest of the canonical JSON representation of the full CallerIdentity object (CallerIdentity::identity_hash). The same identity MUST always produce the same hash.
AuthMethod
A tagged union representing how the caller authenticated. The discriminator field is method. Variant names use snake_case.
| Variant | Tag value | Fields | Description |
|---|---|---|---|
| Bearer | "bearer" | token_hash: string | Bearer token (JWT or opaque). token_hash is the SHA-256 hex hash of the raw token. Implementations MUST NOT store or transmit raw tokens. |
| ApiKey | "api_key" | key_name, key_hash | API key. key_name is the header or query parameter name; key_hash is the SHA-256 hex hash of the key value. |
| Cookie | "cookie" | cookie_name, cookie_hash | Session cookie. cookie_hash is the SHA-256 hex hash of the cookie value. |
| MtlsCertificate | "mtls_certificate" | subject_dn, fingerprint | mTLS client certificate. fingerprint is the SHA-256 fingerprint of the certificate. |
| Anonymous | "anonymous" | (none) | No authentication was presented. CallerIdentity::anonymous() sets subject to "anonymous". |
The specification's Bearer example, with a placeholder hash:
{
"method": "bearer",
"token_hash": "a1b2c3d4e5f6..."
}The Anonymous example:
{
"method": "anonymous"
}SessionContext
Per-session context carried through the Chio HTTP guard pipeline. A session groups related requests from the same caller over a bounded time window.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
session_id | string | MUST | Unique session identifier | |
caller | CallerIdentity | MUST | Authenticated caller for this session | |
created_at | integer | MUST | Unix timestamp (seconds) when the session was created | |
expires_at | integer or null | MAY | null | Unix timestamp (seconds) when the session expires; is_expired() compares it with the current time |
request_count | integer | MAY | 0 | Number of requests evaluated in this session |
bytes_read | integer | MAY | 0 | Cumulative bytes read by this session |
bytes_written | integer | MAY | 0 | Cumulative bytes written by this session |
delegation_depth | integer | MAY | 0 | Current delegation depth. 0 means direct caller. |
metadata | object or null | MAY | null | Extensibility metadata |
Verdict
Internally tagged with "verdict" as the tag key and snake_case variant names.
| Variant | Tag value | Fields | Description |
|---|---|---|---|
| Allow | "allow" | (none) | Request is allowed. Proceed to upstream. |
| Deny | "deny" | reason, guard, http_status, details | Request is denied. http_status defaults to 403. details is a boxed DenyDetails block, omitted from the wire when empty. |
| Cancel | "cancel" | reason | Evaluation was cancelled (e.g., timeout, circuit breaker). |
| Incomplete | "incomplete" | reason | Evaluation did not reach a terminal state. A strict nonce preflight answers with this variant and an execution_nonce. |
Fail-closed semantics
cancel or incomplete, middleware MUST treat the request as denied. Only an explicit allow verdict permits forwarding to the upstream API. The reverse proxy answers an incomplete verdict with 428 Precondition Required and the EvaluateResponse as the body.When deserializing a deny verdict without an explicit http_status field, implementations MUST default to 403; the crate does this through a serde default. The specification's examples:
{ "verdict": "allow" }{
"verdict": "deny",
"reason": "side-effect route requires a capability token",
"guard": "CapabilityGuard",
"http_status": 403
}That deny is the one the HTTP authority emits for a deny-by-default route with no capability presented; an invalid capability yields a deny from the same guard with the validation failure as reason.
DenyDetails
A deny verdict carries an optional boxed DenyDetails block so a sidecar can tell an SDK what scope was required and what scope was granted. Every field is optional; the whole details key is omitted from the wire when all fields are empty.
| Field | Type | Description |
|---|---|---|
tool_name | string or null | Tool that was denied |
tool_server | string or null | Tool server that hosts the denied tool |
requested_action | string or null | Short summary of the attempted action |
required_scope | string or null | Scope the kernel says is required, as a canonical ToolGrant(...) string |
granted_scope | string or null | Scope the presented capability had. Null when none was presented. |
reason_code | string or null | Stable machine-readable code, e.g. scope.missing |
receipt_id | string or null | Receipt id that records this denial, for audit correlation |
hint | string or null | Next-steps sentence for the developer |
docs_url | string or null | Link to the docs page that explains this deny code |
HttpMethod
Serialized as uppercase strings. HttpMethod::is_safe names the first column and requires_capability is its negation.
| Value | Safe | Requires capability |
|---|---|---|
"GET" | Yes | No |
"HEAD" | Yes | No |
"OPTIONS" | Yes | No |
"POST" | No | Yes |
"PUT" | No | Yes |
"PATCH" | No | Yes |
"DELETE" | No | Yes |
Safe methods (GET, HEAD, OPTIONS) are treated as side-effect-free by default and receive session-scoped allow verdicts. Unsafe methods (POST, PUT, PATCH, DELETE) require an explicit capability grant.
GuardEvidence
The same GuardEvidence type the core receipt carries. The HTTP authority emits entries named DefaultPolicyGuard for a session-scoped allow and CapabilityGuard for a capability decision.
| Field | Type | Required | Description |
|---|---|---|---|
guard_name | string | MUST | Name of the guard |
verdict | boolean | MUST | Whether the guard passed (true) or denied (false) |
details | string or null | MAY | Human-readable details about the guard's decision; omitted when absent |
HttpReceipt
A signed receipt proving that an HTTP request was evaluated by the Chio kernel. The receipt binds the request identity, route, method, verdict, semantic classification, and guard evidence under a signature from the kernel (Ed25519 by default; P-256 and P-384 also supported). The Required column reads the serde attributes: a field with a skip rule is omitted from the wire at its default.
| Field | Type | Required | Default | Signed | Description |
|---|---|---|---|---|---|
id | string | MUST | Yes | Content-addressed receipt id: SHA-256 hex of the canonical JSON of the receipt body with id removed (compute_http_receipt_id), computed and assigned inside HttpReceipt::sign. The caller-supplied value is overwritten. | |
request_id | string | MUST | Yes | Unique request ID this receipt covers | |
route_pattern | string | MUST | Yes | Matched route pattern | |
method | HttpMethod | MUST | Yes | HTTP method of the evaluated request | |
caller_identity_hash | string | MUST | Yes | SHA-256 hex hash of the caller identity | |
session_id | string or null | MAY | null | Yes | Session ID the request belonged to |
verdict | Verdict | MUST | Yes | The kernel's verdict | |
receipt_kind | ReceiptKind | MUST | Yes | Signed semantic class. Signing rejects any value other than mediated_decision. | |
boundary_class | BoundaryClass | MUST | Yes | Signed runtime boundary. Signing rejects any value other than prevent. | |
observation_outcome | ObservationOutcome or null | MUST NOT | null | Yes | Absent on mediated HTTP receipts; signing rejects a present value. |
tool_origin | ToolOrigin | MUST | Yes | Where the protected effect executes relative to Chio: caller_executed, host_executed_provider_reported, or host_executed_unmediated. The HTTP authority writes caller_executed. | |
redaction_mode | RedactionMode | MUST | Yes | Redaction applied to signed details: none, summary, or redacted. The HTTP authority writes none. | |
actor_chain | ActorRef[] | MAY | [] | Yes | Signed actor attribution for the HTTP decision. Omitted from the wire when empty. |
evidence | GuardEvidence[] | MAY | [] | Yes | Per-guard evidence collected during evaluation. Omitted from the wire when empty. |
response_status | integer | MUST | Yes | HTTP status Chio associated with the evaluation outcome at receipt-signing time. For deny receipts, the error status Chio emits; for allow receipts signed before an upstream response exists, evaluation-time metadata. | |
timestamp | integer | MUST | Yes | Unix timestamp (seconds) when the receipt was created | |
content_hash | string | MUST | Yes | SHA-256 hex hash binding the request content to this receipt | |
policy_hash | string | MUST | Yes | SHA-256 hex hash of the policy that was applied | |
trust_level | TrustLevel | MUST | Yes | Strength of kernel mediation. Signing rejects any value other than mediated. | |
capability_id | string or null | MAY | null | Yes | Capability ID that was exercised, if any |
metadata | object or null | MAY | null | Yes | Extensibility metadata. The reverse proxy writes chio_http_status_scope (decision or final) and, on a finalized receipt, chio_decision_receipt_id. |
kernel_key | PublicKey (hex) | MUST | Yes | Kernel's algorithm-aware public key (the same chio_core_types::crypto::PublicKey as the core receipt): bare 64-hex Ed25519, p256:<130-hex>, or p384:<194-hex> | |
signature | Signature (hex) | MUST | No | Algorithm-aware signature over canonical JSON of the body fields: bare 128-hex Ed25519, or a p256: or p384: prefixed form |
Signing
HttpReceipt::sign(body, keypair) produces a signed receipt in this order:
- Construct an
HttpReceiptBodycontaining every field in the table exceptsignature. - Compute the content-addressed
id(compute_http_receipt_id) and overwrite the body'sidwith it. - Validate the authority semantics:
mediated_decision,prevent, noobservation_outcome,mediated. Any other shape is an error. - Serialize the body to canonical JSON (RFC 8785) and sign the canonical bytes with the kernel's private key (Ed25519 by default; P-256 or P-384 when configured).
- Attach the resulting signature to the receipt.
Verification
HttpReceipt::verify_signature returns false at the first failing step:
- Extract the body (all fields except
signature) and validate the authority semantics. - Recompute the content-addressed id and compare it with
id. - Serialize the body to canonical JSON (RFC 8785) and verify the signature against the canonical bytes using the
kernel_keyembedded in the receipt.
Implementations SHOULD verify the receipt signature before treating receipt content as authoritative.
Cryptographic representations
kernel_key and signature reuse the algorithm-aware chio_core_types::crypto types of the core ChioReceipt, so they are not restricted to bare Ed25519 hex:
kernel_key: bare 64-character lowercase hex for Ed25519,p256:<130-hex>(uncompressed SEC1), orp384:<194-hex>.signature: bare 128-character lowercase hex for Ed25519, or ap256:orp384:prefixed DER hex form. Verification dispatches on the prefix.
HttpReceipt to ChioReceipt mapping
An HttpReceipt maps into the core ChioReceipt type for unified storage and querying. There are two methods, and the no-argument one fails closed:
to_chio_receipt()(no argument) always returns an error ("cannot convert HttpReceipt into signed ChioReceipt without the kernel keypair"), because a copied HTTP signature would not verify over theChioReceiptBody.to_chio_receipt_with_keypair(keypair)builds theChioReceiptBody, recomputescontent_hashover that canonical body, and re-signs throughChioReceipt::sign(...)with the supplied kernel keypair. The HTTP signature is never copied.
Field mapping
| HttpReceipt field | ChioReceipt field | Transformation |
|---|---|---|
id | id | Copied directly |
timestamp | timestamp | Copied directly |
capability_id | capability_id | Unwrapped; defaults to the empty string if null |
| (constant) | tool_server | Set to "http" |
method + route_pattern | tool_name | Formatted as "{method} {route_pattern}" |
method, route_pattern, request_id | action.parameters | JSON object { method, route, request_id } |
| (derived) | action.parameter_hash | Canonical hash of action.parameters (through ToolCallAction::from_parameters), so a durable store that recomputes the hash accepts the converted receipt. The HTTP content_hash stays bound through its own field. |
verdict | decision | Converted through Verdict::to_decision() |
receipt_kind, boundary_class, observation_outcome, tool_origin, redaction_mode, actor_chain | (same fields) | Copied directly |
content_hash | content_hash | Recomputed as SHA-256 of the canonical JSON of the ChioReceiptBody |
policy_hash | policy_hash | Copied directly |
evidence | evidence | Copied directly |
metadata | metadata | Copied directly |
trust_level | trust_level | Copied directly |
| (constant) | tenant_id | Set to null |
| (constant) | bbs_projection_version | Set to null |
kernel_key | kernel_key | Copied directly |
| (re-signed) | signature | Freshly produced by ChioReceipt::sign(...) with the supplied keypair. The HTTP signature is never copied. |
Verdict to Decision mapping
| Verdict variant | Decision variant |
|---|---|
allow | allow |
deny { reason, guard, http_status, details } | deny { reason, guard } (http_status and details are dropped) |
cancel { reason } | cancelled { reason } |
incomplete { reason } | incomplete { reason } |
The reverse mapping, Verdict::from(Decision), restores a deny with http_status 403 and empty details.
Conversion re-signs or fails closed
No-argument conversion fails closed
to_chio_receipt() takes no keypair and unconditionally returns an error. A ChioReceipt signature cannot be derived from an HttpReceipt alone, so the conversion refuses instead of emitting a receipt whose signature would fail standard verification.Use to_chio_receipt_with_keypair(keypair) for conversion. It recomputes content_hash over the canonical ChioReceiptBody and re-signs with the kernel keypair, producing a ChioReceipt whose signature and action.parameter_hash verify, so a durable receipt store accepts it.
Default policy semantics
The HTTP sidecar protocol defines default policy behavior based on HTTP method safety:
- Safe methods (GET, HEAD, OPTIONS): session-scoped allow, recorded as a passing
DefaultPolicyGuardevidence entry. - Unsafe methods (POST, PUT, PATCH, DELETE): deny by default. These methods require a capability token presented in the
X-Chio-Capabilityrequest header, thechio_capabilityquery parameter, orcapability_idin theChioHttpRequest.
When a route is not matched in the loaded policy, the evaluator MUST fall back to method-based default policy. The reverse proxy then records the raw path as route_pattern.
Error handling
Sidecar error codes
SDKs MUST use the following error codes when communicating sidecar failures to callers. The TypeScript node-http package exports these five and one more, chio_sidecar_unavailable, as ChioErrorCode; it classifies a verify response of 408, 404, 429, or 5xx under that code.
| Code | Meaning |
|---|---|
chio_access_denied | The request was denied by policy |
chio_sidecar_unreachable | The sidecar process is not reachable |
chio_evaluation_failed | The sidecar returned a non-200 status |
chio_invalid_receipt | Receipt verification failed |
chio_timeout | The sidecar did not respond within the timeout |
The sidecar itself answers with these codes in its own JSON error bodies:
| Code | Status | When |
|---|---|---|
chio_bad_request | 400 | The body could not be read or decoded; a duplicate query key; a blank or malformed x-chio-execution-nonce header |
chio_access_denied | 403 (or the verdict's http_status) | The proxy denied a forwarded request; the body carries message, receipt_id, and suggestion |
chio_approval_required | 409 | Evaluation returned a pending approval |
chio_evaluation_failed | 500 | Any other evaluation error |
chio_receipt_sign_failed | 500 | The revocation receipt could not be hashed or signed |
chio_receipt_persistence_failed | 500 | The receipt could not be recorded |
Structured error response
When middleware denies a request, the response body SHOULD be a structured JSON object. The reverse proxy's 403 body carries all four fields and repeats the receipt id in an X-Chio-Receipt-Id header.
| Field | Type | Required | Description |
|---|---|---|---|
error | string | MUST | Error code from the table of sidecar error codes |
message | string | MUST | Human-readable error message; the proxy uses the verdict's reason |
receipt_id | string or null | MAY | Receipt ID for the denied evaluation |
suggestion | string or null | MAY | Actionable suggestion for the caller |
Schemas and conformance
Versioned HTTP sidecar schemas live under spec/schemas/chio-http/v1/. Schema files in that directory are the machine-readable contract for the HTTP sidecar types. Implementations MUST serialize all HTTP sidecar types in a form accepted by those schemas. Schema validation SHOULD be exercised against live Rust serialization and never against handwritten examples alone.
The directory holds 15 schema files; the schema registry lists 0 of them. The table names every file with the title it declares.
| File | Declared title |
|---|---|
caller-identity.schema.json | Chio CallerIdentity |
chio-http-request.schema.json | Chio HTTP Request |
error-envelope.schema.json | Chio HTTP Error Envelope |
evaluate-request.schema.json | Chio Evaluate Request |
evaluate-response.schema.json | Chio Evaluate Response |
finding-hosted-domain-event.schema.json | Chio Hosted Finding Domain Event Envelope |
finding-hosted-error.schema.json | Chio Hosted Finding Error |
finding-hosted-mutation-response.schema.json | Chio Hosted Finding Mutation Response |
finding-hosted-request-context.schema.json | Chio Hosted Finding Authenticated Request Context |
finding-hosted-tenant-binding.schema.json | Chio Hosted Finding Tenant Binding |
http-receipt.schema.json | Chio HTTP Receipt |
session-init.schema.json | Chio HTTP Session Init |
session-resume.schema.json | Chio HTTP Session Resume |
stream-frame.schema.json | Chio HTTP Stream Frame |
verdict.schema.json | Chio HTTP Verdict |
evaluate-request.schema.json is a reference to chio-http-request.schema.json. The session, stream, error-envelope, and hosted-finding schemas describe the chio-http edge and the hosted finding API, which this page does not cover.
| file | title | registry id | version |
|---|---|---|---|
chio-http/v1/caller-identity.schema.json | Chio CallerIdentity | unregistered | v1 |
chio-http/v1/chio-http-request.schema.json | Chio HTTP Request | unregistered | v1 |
chio-http/v1/error-envelope.schema.json | Chio HTTP Error Envelope | unregistered | v1 |
chio-http/v1/evaluate-request.schema.json | Chio Evaluate Request | unregistered | v1 |
chio-http/v1/evaluate-response.schema.json | Chio Evaluate Response | unregistered | v1 |
chio-http/v1/finding-hosted-domain-event.schema.json | Chio Hosted Finding Domain Event Envelope | unregistered | v1 |
chio-http/v1/finding-hosted-error.schema.json | Chio Hosted Finding Error | unregistered | v1 |
chio-http/v1/finding-hosted-mutation-response.schema.json | Chio Hosted Finding Mutation Response | unregistered | v1 |
chio-http/v1/finding-hosted-request-context.schema.json | Chio Hosted Finding Authenticated Request Context | unregistered | v1 |
chio-http/v1/finding-hosted-tenant-binding.schema.json | Chio Hosted Finding Tenant Binding | unregistered | v1 |
chio-http/v1/http-receipt.schema.json | Chio HTTP Receipt | unregistered | v1 |
chio-http/v1/session-init.schema.json | Chio HTTP Session Init | unregistered | v1 |
chio-http/v1/session-resume.schema.json | Chio HTTP Session Resume | unregistered | v1 |
chio-http/v1/stream-frame.schema.json | Chio HTTP Stream Frame | unregistered | v1 |
chio-http/v1/verdict.schema.json | Chio HTTP Verdict | unregistered | v1 |
spec/schemas/registry.jsonat fe56570Related
- Wire Protocol: the agent-to-kernel wire format and the hosted MCP session transport.
- Protocol Reference: the capability and receipt contract the HTTP types build on.
- OpenAPI Integration: the
chio api protectflags, the OpenAPI conversion, and the proxy's status mapping. - Protect an API: running the proxy in front of an upstream.
- Schemas and Errors: the schema registry and the error registry.