Chio/Docs
LOGIN · JOIN

Core & Shell

See which authority checks run anywhere the Rust core builds, and which need the hosted kernel's state, dispatch, and receipts.

Concept chio@5f63e6e

On this page

The same authority decision runs in a browser, on a phone, inside a C++ host, and in the hosted kernel. Chio puts that decision in chio-kernel-core, a Rust library that builds with no_std + alloc, and puts everything that touches state, tools, or storage in chio-kernel.

A host hands the core the request context, its trusted keys, a clock, its guards, and any delegated-share registry. The core evaluates what it was handed and owns no tool connection and no receipt database. The hosted kernel calls the same verification code, then adds live revocation, request-bound approval, spending admission, tool dispatch, and durable evidence.

The core decides from what the host gives it

The full portable entry point runs five stages in order. Any stage can deny, and only a request that passes all five is allowed.

Kernel partsChoose a phase or a part.
Outside the processdecision coreno_std + allocoutsidekernel processdecision core

The decision core holds the pure checks

Pure computation with no I/O. The same crate is built into the browser, mobile, and C++ adapters. The bounded verified core covers its evaluate function and the runtime’s evaluate_portable_verdict, which delegates to it. Portable kernel.

capability verificationcapability_verify

verify_capability_full_with_root checks the issuer against the trusted roots, the signature, and the validity window, and mutates nothing.

sibling budgetstrait BudgetRegistry

Admits a delegated child’s share of its parent’s allocation last, so a call refused before this step never consumes a sibling’s share.

clock and entropytrait Clock, trait Rng

Traits for time and randomness, so a browser, mobile, or test host supplies its own. The core has no system clock of its own.

receipt signingsign_receipt

Recomputes the content hash over the canonical content inside the trust boundary. A mismatch prevents signing.

The core also carries two parts for hosts that link it alone; the native runtime does their jobs in its own modules.

portable scope matchresolve_matching_grants

The core’s grant matcher, used by its evaluate on browser, mobile, and FFI hosts. The native runtime matches grants in its own request_matching module.

guard pipelinetrait Guard

The synchronous Guard trait the core’s evaluate runs, failing closed on an error. The runtime’s guard runner calls guards with the same signature.

In Rust · evaluate.rs:13
//! What it does NOT do (fenced into `chio-kernel` proper):
//!
//! - Revocation membership lookup (stateful `RevocationStore`).
//! - Budget mutation (stateful `BudgetStore`).
//! - Delegation-chain ancestor inspection against the receipt store.
//! - DPoP proof verification with nonce replay (LRU-backed).
//! - Governed-transaction policy evaluation (pulls in chio-governance).
//! - Payment authorisation (async adapter trait).
//! - Tool dispatch to wrapped servers (async transport).
//! - Receipt persistence / Merkle checkpointing (SQL / IO).
The hosted kernel process and the decision core it calls. The core is shared by the browser, mobile, and C++ adapters; the hosted kernel reaches the stores and tool servers drawn outside the process.Portable kernel
  1. Verify authority. The issuer, signature, time bounds, crypto floor, negotiated features, and required root evidence. A denial here means an untrusted issuer, an invalid signature, expired authority, a rejected crypto or feature family, or an invalid chain binding.
  2. Bind the subject. The request's agent must match the capability's verified subject.
  3. Match a grant. A tool and server grant must apply and its constraints must hold. A constraint the portable matcher cannot enforce denies.
  4. Run guards. Each supplied synchronous guard must return Allow. Deny, PendingApproval, or an error stops the request.
  5. Admit the delegated share. A delegated child is admitted against the sibling-budget registry. An unknown parent, or a child that would oversubscribe the parent's allocation, denies.

Read more in Portable Kernel.

A delegated share is admitted only after the request checks pass

A validly signed token presented for the wrong agent or tool consumes no sibling share, because share admission runs after subject binding, grant matching, and guards. The registry is explicit, mutable state that the caller owns, so the portable path is a function of the request and that registry together.

The plain evaluate entry point uses AllowClassical and a NoopBudgetRegistry, which enforces no sibling-sum bound. Integrations that need configured crypto policy, negotiated features, trust-root evidence, and sibling admission call the richer entry points, up to evaluate_with_full_floor_and_root.

The portable input type
crates/kernel/chio-kernel-core/src/evaluate.rs57-71rust
pub struct EvaluateInput<'a> {
    /// Tool call request being evaluated.
    pub request: &'a PortableToolCallRequest,
    /// The capability token authorising this call.
    pub capability: &'a CapabilityToken,
    /// Trusted issuer public keys (typically CA + kernel + authority).
    pub trusted_issuers: &'a [PublicKey],
    /// Clock used for time-bound enforcement.
    pub clock: &'a dyn Clock,
    /// Guard pipeline. Evaluated in order, fail-closed on deny or error.
    pub guards: &'a [&'a dyn Guard],
    /// Optional filesystem roots from the owning session, passed through to
    /// guards that enforce root-based resource protection.
    pub session_filesystem_roots: Option<&'a [String]>,
}

BudgetRegistry admits child shares of a parent capability. Money is a different store: the hosted BudgetStore owns monetary holds and accounting, and the portable evaluator reserves no payment, captures no money, and reconciles no tool charge.

Eight services live in the hosted kernel

The evaluator's module names the services it leaves to the host. Each one depends on state the core never holds:

  • Revocation: a current view of revoked capabilities and their ancestors.
  • Spend accounting: reservations, charges, release, and reconciliation in the runtime budget store.
  • Delegation joins: stored capability snapshots and ancestor inspection.
  • Proof-of-possession replay checks: a nonce store that remembers accepted proofs.
  • Governed transactions and approval: the applicable charter, authorization evidence, and pending-work state.
  • Payment authorization: the configured async payment adapter.
  • Tool dispatch: the tool connection, execution environment, and output policy.
  • Receipt retention: persistence, ordering, recovery, and Merkle checkpointing.

A no-I/O evaluator can still call an injected trait whose implementation reads state, so an integration accounts for its guards, clock, root resolver, and registry. To reproduce a decision, keep those inputs and their state with the request.

Read more in The State a Verdict Depends On.

Enforcement the core cannot perform denies

Portable evaluation returns Allow or Deny. A synchronous guard that asks for human approval is denied, because the core has no approval workflow to run. The full current-semantics entry point also rejects capabilities that require aggregate-invocation or cumulative-approval enforcement.

Scope matching on this path covers tool grants. A constraint that needs context the core lacks fails closed instead of being skipped. The hosted matcher reads more context, including model metadata, so read an Allow under the contract of the entry point that produced it.

Read more in Verdicts & Approval.

The hosted call adds state, dispatch, and evidence

The hosted call path checks runtime readiness and capability admission, runs the applicable revocation and delegation checks, binds the request, matches its grants, and runs the configured guards. Where the request and policy require them, it adds proof of possession, approval, budget, and payment. Only an admitted invocation proceeds to execution.

After execution, output hooks can transform or withhold the result, and the runtime finalizes accounting and the signed receipt for the outcome. A signing, storage, or readiness failure fails the call, so a portable Allow says nothing about whether those services completed.

Callers that execute at a separate enforcement site use the pre-execution authorization path. It reserves an open hold and mints an execution nonce without dispatching the tool, and its preflight receipt is non-authoritative: it records no completed spend. Receipts separates authorization, completion, and settlement.

Each entry point promises a different result

Four entry families share the verification primitives and promise different results:

Entry pointDispatchesReceiptState it reads
chio_kernel_core::evaluate*NoNone persistedSupplied context and registry
evaluate_portable_verdictNoNone persistedTrusted issuers, features, root context, budget registry
evaluate_tool_call_*YesSigned and storedLive stores and configured services
authorize_tool_call_reserving_*ElsewhereNon-authoritative preflightOpen hold, reconciled at the execution site

evaluate_portable_verdict is a hosted wrapper around the full portable evaluator. It reads retained root-capability evidence when negotiated features require it, so preparing a portable call can touch the database. The hosted execution path has its own request matcher and orchestration.

The browser binding runs a capability-only evaluation with no guard pipeline. It reports the result as diagnostic authority evidence with authorized: false, and never as permission to execute.

Read more in Portable Kernel, which compares the platform contracts.

Shared predicates carry the rules; hosts supply the state

Beside capability checks, scope matching, guard evaluation, and receipt signing, the core exports small decision predicates for guards, budgets, proof of possession, delivery, and other transitions, and runtime code consumes some of them. A predicate states the rule and gives formal checks a target. The storage, clock, and network state fed to it comes from the host.

The optional revocation-view feature provides a hosted snapshot facility and implies std. The portable no-default-features build leaves it out, and the portable evaluator consults it only when a host wires it in. The portability script builds the core for the host and for wasm32-unknown-unknown with default features disabled; each adapter's surrounding enforcement is its own.

Formal claims attach to named functions and models with stated assumptions; the formal assurance boundary marks where they stop. What a signed receipt establishes is set out once in the assurance model.

Source

Next: embed the portable core