Chio/Docs
LOGIN · JOIN

EconomyOther Companies

Bilateral Federation

Two Chio kernels establish a direct, per-pair trust relationship through a signed handshake and pinned keys.

Bilateral trust relationships

Each cross-kernel relationship has two participants. Org A pins Org B's kernel key, and Org B pins Org A's key. Trust does not extend to a third operator. Calls from A to tools at C require a separate A-to-C handshake. Chio does not operate a root identity provider.

  • No global identity provider: identity is the Ed25519 kernel keypair on each side, exchanged out of band and pinned locally.
  • No silent transitivity: a verifier checking a receipt from another org refuses unless the issuing kernel id matches a peer it has pinned.
  • Symmetric per-pair terms: rotation windows, handshake skew, and import controls live in each kernel's local configuration.

Bilateral co-sign covers two kernels. An operation that needs a quorum larger than two uses the FROST threshold-signature implementation in chio-federation/src/frost/. See Cross-Org Swarms.

Key pinning and capability authorization

Pinning a peer kernel enables verification of its signed records. An agent in the peer organization still needs an attenuated child capability that satisfies local policy to call a tool.

The KernelTrustExchange handshake

Two kernels bootstrap mutual trust by exchanging signed challenges and pinning each other's kernel signing public keys. The type is KernelTrustExchange, defined in chio-federation::trust_establishment. It is mTLS-style: both sides authenticate, both sides confirm key material, neither side accepts the other on weight of name alone.

The handshake body is HandshakeChallenge at chio-federation/src/trust_establishment.rs:229:

crates/trust/chio-federation/src/trust_establishment.rsrust
pub const FEDERATION_HANDSHAKE_SCHEMA: &str = "chio.federation-kernel-handshake.v1";

// ...

/// Challenge body signed by one kernel during the handshake.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct HandshakeChallenge {
    pub schema: String,
    pub local_kernel_id: String,
    pub remote_kernel_id: String,
    pub nonce: String,
    pub timestamp: u64,
    #[serde(default, skip_serializing_if = "is_default_capability_negotiation")]
    pub capabilities: CapabilityNegotiation,
    #[serde(default, skip_serializing_if = "is_default_conformance_tier")]
    pub conformance_tier: ConformanceTier,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub ladder_manifest_ref: Option<LadderManifestRef>,
}

The last three fields carry capability negotiation and conformance-ladder metadata; each is skip_serializing_if at its default, so a minimal challenge serializes to the five required fields above.

Each kernel signs the canonical-JSON encoding of its challenge and wraps the result in a PeerHandshakeEnvelope (trust_establishment.rs:312):

crates/trust/chio-federation/src/trust_establishment.rsrust
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct PeerHandshakeEnvelope {
    pub challenge: HandshakeChallenge,
    pub declared_public_key: PublicKey,
    pub signature: Signature,
}

The remote side calls accept_envelope at trust_establishment.rs:749 with the envelope, the expected remote kernel id, and the local clock. It delegates to accept_envelope_with_policy with a default QuorumPolicy, and enforces seven steps in order:

  1. envelope.verify_signature() checks that the canonical-JSON challenge bytes verify under the declared public key (trust_establishment.rs:444).
  2. The envelope's challenge.remote_kernel_id MUST equal the local kernel id, otherwise AddressMismatch.
  3. The envelope's challenge.local_kernel_id MUST equal the expected peer id, otherwise KernelIdMismatch.
  4. envelope_ts.abs_diff(now) MUST be within max_handshake_skew_secs (default DEFAULT_HANDSHAKE_MAX_SKEW_SECS = 5 * 60 at trust_establishment.rs:57), otherwise ClockSkewExceeded.
  5. The declared key MUST match either an anchor installed via with_trusted_peer (trust_establishment.rs:666) or an already-pinned peer's key. Missing anchor returns MissingTrustAnchor; mismatched anchor returns UnexpectedPeerKey carrying both expected and actual hex.
  6. The peer's negotiated challenge.conformance_tier MUST satisfy the quorum policy's min_tier (QuorumPolicy::accepts_tier; accept_envelope uses the default floor of Bronze, a stricter floor is passed through accept_envelope_with_policy). A tier below the floor fails closed with ConformanceTierBelowMinimum before any peer is constructed or pinned.
  7. On success, the remote key is pinned as a fresh FederationPeer with rotation_due = now + rotation_window_secs (default DEFAULT_ROTATION_WINDOW_SECS = 12 * 60 * 60 at trust_establishment.rs:52).

Out-of-band key pinning is required

First contact has no authentication other than a pre-configured trust anchor. If neither side already knows the other's public key, the operator must install one through with_trusted_peer(kernel_id, public_key) before the handshake will be accepted. Without an anchor, accept_envelope fails with MissingTrustAnchor.
rust
use chio_federation::trust_establishment::{
    KernelTrustExchange, PeerHandshakeEnvelope,
};

// Org A side: install a trust anchor for Org B and accept their envelope.
let exchange = KernelTrustExchange::new("org-a-kernel", org_a_keypair)
    .with_trusted_peer("org-b-kernel", org_b_public_key.clone());

let envelope_from_b: PeerHandshakeEnvelope = receive_handshake_envelope();
let now = unix_seconds_now();
let peer = exchange.accept_envelope(&envelope_from_b, "org-b-kernel", now)?;

// 'peer' is now pinned. peer.is_fresh(now) returns true until rotation_due.
assert!(peer.is_fresh(now));

Where the handshake runs

The exchange is an in-process Rust call on each side. One kernel builds its envelope with local_envelope (trust_establishment.rs:706) and the other hands the bytes it received to accept_envelope. The trust control plane registers no handshake route. Its federation group is these 7 paths:

PathMethodsHandlers
/v1/federation/capabilities/issuePOSThandle_federated_issue
/v1/federation/evidence-sharesGEThandle_shared_evidence_report
/v1/federation/open-admission-policiesGEThandle_list_federation_policies
/v1/federation/open-admission-policies/evaluatePOSThandle_evaluate_federation_policy
/v1/federation/open-admission-policies/{policy_id}DELETE, GET, PUThandle_get_federation_policy, handle_upsert_federation_policy, handle_delete_federation_policy
/v1/federation/providersGEThandle_list_enterprise_providers
/v1/federation/providers/{provider_id}DELETE, GET, PUThandle_get_enterprise_provider, handle_upsert_enterprise_provider, handle_delete_enterprise_provider

Carrying the envelope between the two operators is the deployment's choice, and that choice does not change what is trusted. The signature covers the canonical-JSON HandshakeChallenge bytes, so a transport supplies confidentiality and channel authentication and supplies nothing to handshake authenticity. Chio ships one federation transport, chio-federation-transport-iroh, which mounts each lane on its own ALPN over QUIC; the co-sign lane is chio/federation/bilateral-dsse-cosign/1 (chio-federation-transport-iroh/src/lanes/bilateral.rs:88). That lane carries co-signature requests between peers that are already pinned, so it presumes the handshake rather than performing it.

After both sides accept, each holds a fresh FederationPeer whose rotation_due is the accepting kernel's own clock plus rotation_window_secs, twelve hours by default. The envelope timestamp is checked for skew and does not set the window.


The federation peer set

Successful handshakes leave the local kernel with a set of pinned peers. ChioKernel exposes these methods around that set, defined in chio-kernel/src/kernel/construction.rs:

MethodPurposeSource
with_federation_peers(self, peers: Vec<FederationPeer>) -> SelfBuilder-style; install the trusted peer set during kernel construction. Replaces any prior set. Marked #[must_use].construction.rs:1152
set_federation_cosigner(&mut self, cosigner)Install the bilateral cosigner that contacts a peer kernel for a co-signature. Tests use InProcessCoSigner; production uses an mTLS RPC client.construction.rs:1264
set_federation_local_kernel_id(&self, id)Advertise this kernel's stable id (e.g. a DNS name) to remote peers. Defaults to the hex encoding of the signing public key.construction.rs:1299
federation_peer(&self, remote_kernel_id, now) -> Option<FederationPeer>Resolve a peer; returns None when unknown OR when !peer.is_fresh(now). Stale pins fail closed at the lookup, not at the call site.construction.rs:1306
federation_peers_snapshot(&self) -> Vec<FederationPeer>Cloned snapshot of all currently-pinned peers.construction.rs:1321

Exact method names

The setter is with_federation_peers (builder, not set_federation_peers), the resolver is federation_peer(remote_kernel_id, now) (not resolve_federation_peer), and the local-id setter is set_federation_local_kernel_id (singular).

The pinned peer record is FederationPeer:

crates/trust/chio-federation/src/trust_establishment.rs192-216rust
/// Pinned federation peer entry.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct FederationPeer {
    pub kernel_id: String,
    pub public_key: PublicKey,
    /// Cross-surface conformance tier that was signed into the peer's most
    /// recent accepted handshake.
    #[serde(default)]
    pub conformance_tier: ConformanceTier,
    /// Unix seconds at which the peer was last pinned via a successful
    /// handshake.
    pub established_at: u64,
    /// Unix seconds at which the pin expires. After this timestamp the
    /// peer is treated as stale and MUST be re-handshaked before any
    /// federation-level operation is accepted against it.
    pub rotation_due: u64,
    /// Peer-advertised protocol feature bitset. Missing on compatibility peers
    /// defaults to current capability semantics without optional features.
    #[serde(default)]
    pub capabilities: CapabilityNegotiation,
    /// Optional signed ladder manifest reference accepted during handshake.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub ladder_manifest_ref: Option<LadderManifestRef>,
}

The last three fields are populated from the same HandshakeChallenge capability-negotiation and conformance-ladder metadata described above: conformance_tier is the tier the peer signed into its accepted handshake, capabilities is the negotiated protocol feature bitset, and ladder_manifest_ref is the optional signed ladder reference. All three carry serde defaults, so a compatibility peer that omits them still pins. Freshness is one comparison, FederationPeer::is_fresh(now) -> now < self.rotation_due (trust_establishment.rs:221).

Stale peers fail closed

After rotation_due, the kernel returns None from federation_peer and any federation operation that depends on the peer must refuse. The two kernels MUST re-run the handshake before further bilateral traffic is accepted; rotation never silently renews.

Bilateral federation policy

The handshake establishes who you are talking to. Separate signed policy records describe what each side will accept across the boundary. Two interfaces are distinct:

  • chio trust federation-policy manages an open-admission policy (chio.federation-open-admission-policy.v1) scoped to a federation namespace, not a per-partner record. Verbs are list, get, upsert, delete, and evaluate; upsert reads --input <json-file> and writes an optional local --federation-policies-file <path>.
  • chio evidence federation-policy create signs a bilateral receipt-sharing policy for a specific issuer/partner pair. This record differs from the admission policy above.

The open-admission record is FederatedOpenAdmissionPolicyArtifact (chio-federation/src/open_admission.rs):

FieldPurpose
policy_idStable id of the admission policy record.
namespaceFederation namespace the policy governs.
governing_operator_idOperator that owns and signs the policy.
allowed_admission_classesAdmission classes a peer may enter under this policy (public_untrusted, reviewable, bond_backed, role_gated).
stake_requirementsPer-class bond requirements: bond class, minimum amount, slashability, and whether a governance case is required.
governing_charter_refReference to the charter that authorizes the policy.
fee_schedule_refReference to the open-market fee schedule that prices participation.
explicit_local_review_requiredWhether local review must precede admission.
visibility_only_without_activationWhether a peer stays visibility-only until explicit local activation.

A per-pair activation attaches scope, delegation, and import controls to a signed exchange between two operators. FederationActivationExchangeArtifact at chio-federation/src/activation.rs:19:

crates/trust/chio-federation/src/activation.rsrust
pub const CHIO_FEDERATION_ACTIVATION_EXCHANGE_SCHEMA: &str =
    "chio.federation-activation-exchange.v1";

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct FederationActivationExchangeArtifact {
    pub schema: String,
    pub exchange_id: String,
    pub issued_at: u64,
    pub expires_at: u64,
    pub source_operator_id: String,
    pub target_operator_id: String,
    pub listing_id: String,
    pub activation_ref: FederationArtifactReference,
    pub listing_ref: FederationArtifactReference,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub governing_charter_ref: Option<FederationArtifactReference>,
    pub scope: FederationTrustScope,
    pub delegation_control: FederationDelegationControl,
    pub import_control: FederationImportControl,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub note: Option<String>,
}

SignedFederationActivationExchange is an alias for SignedExportEnvelope<FederationActivationExchangeArtifact> (activation.rs:38), and that envelope is rename_all = "camelCase", deny_unknown_fields over exactly three keys, body, signerKey and signature (chio-core-types/src/receipt/lineage.rs:407-417). A fourth key fails deserialization. The schema id is hyphenated, chio.federation-activation-exchange.v1; the literal string is checked, and validate_federation_activation_exchange rejects any other value with UnsupportedSchema. An Ed25519 PublicKey and Signature both serialize as bare lowercase hex with no algorithm prefix; the prefixed forms p256:, p384: and hybrid: are reserved for the other key material (chio-core-types/src/crypto.rs:581 and :791). The block below carries illustrative values in real field names, not captured data; a bracketed value marks a digest, key, or signature this page has not captured.

json
{
  "body": {
    "schema": "chio.federation-activation-exchange.v1",
    "exchangeId": "fex-org-a-org-b-001",
    "issuedAt": 1714291200,
    "expiresAt": 1716883200,
    "sourceOperatorId": "org-a",
    "targetOperatorId": "org-b",
    "listingId": "listing-billing-readonly",
    "activationRef": {
      "kind": "trust_activation",
      "schema": "chio.registry.trust-activation.v1",
      "artifactId": "activation-org-b-77",
      "operatorId": "org-b",
      "sha256": "<64 hex: sha256 of the activation artifact>"
    },
    "listingRef": {
      "kind": "listing",
      "schema": "chio.registry.listing.v1",
      "artifactId": "listing-billing-readonly",
      "operatorId": "org-b",
      "sha256": "<64 hex: sha256 of the listing artifact>"
    },
    "scope": {
      "namespace": "billing.org-b.internal",
      "subjectOperatorId": "org-b",
      "allowedActorKinds": ["tool_server"],
      "allowedAdmissionClasses": ["bond_backed"]
    },
    "delegationControl": {
      "delegatorOperatorId": "org-a",
      "delegateOperatorId": "org-b",
      "maxHops": 1,
      "attenuationRequired": true,
      "visibilityOnlyUntilLocalActivation": true
    },
    "importControl": {
      "explicitLocalActivationRequired": true,
      "manualReviewRequired": true,
      "rejectStaleInputs": true,
      "allowVisibilityWithoutRuntimeTrust": true,
      "prohibitAmbientRuntimeAdmission": true
    }
  },
  "signerKey": "<64 hex: the signing operator's Ed25519 public key>",
  "signature": "<128 hex: Ed25519 over the canonical JSON of body>"
}

The default FederationImportControl (chio-federation/src/artifacts.rs:63) is conservative across all five booleans, so even after the record lands in the local store no runtime traffic is admitted until the operator explicitly opts in.


Cross-org capability issuance

With the peer set pinned and a partner policy stored, an authority in Org A can mint a capability that is honored at Org B. The endpoint is POST /v1/federation/capabilities/issue on the trust control plane.

Request fields, in addition to the standard issuance body:

FieldMeaning
presentationPassport presentation proving federated subject identity.
expectedChallengeChallenge value the presentation must satisfy.
capabilityRequested issued capability body.
delegationPolicyOptional signed ceiling for delegated issuance. Trust-control rejects untrusted signers.
upstreamCapabilityIdOptional imported parent capability anchor for multi-hop lineage.

Normative rules from the shipped service:

  • When upstreamCapabilityId is supplied, a delegation policy bound to that exact parent capability id MUST also be present.
  • When a delegation policy is supplied, the requested child capability MUST NOT exceed the policy ceiling.
  • The trust-control service MUST reject untrusted delegation-policy signers.

The success-response fields that carry the delegation, out of the wider FederatedIssueResponse (chio-control-plane/src/trust_control/service_types/requests.rs:50):

FieldMeaning
capabilityNewly issued child capability.
delegationAnchorCapabilityIdOptional lineage anchor persisted by trust-control.
subjectPublicKeyResolved subject key used for issuance.

Delegation anchor and child snapshot

When trust-control issues a delegated cross-org capability, it persists two records into capability lineage: the new local delegation anchor, and a child snapshot rooted at that anchor. The anchor is identified by the returned delegationAnchorCapabilityId and is the parent of the issued child. When upstreamCapabilityId is present, the anchor also bridges to the imported upstream capability so multi-hop lineage reconstructs truthfully through both organizations.

Lineage for offline audit

After issuance, querying the receipt and lineage stores at Org B for the child capability id walks the chain back through the delegation anchor and across the bridge to the upstream parent at Org A. Auditors verify the full chain without coordinating with either kernel at runtime.

Why bilateral instead of global

A global identity network would require every operator to accept a shared root, accept changes to that root by majority or committee, and accept that revocation propagates through someone else's schedule. Bilateral federation avoids all three questions.

  • No shared root: every operator pins keys it has out-of-band reason to trust. There is no key whose compromise breaks the whole network.
  • Per-pair negotiation: rotation windows, autonomy ceilings, evidence freshness, and re-export configuration are negotiated by the two operators and recorded in their own configurations.
  • Bounded blast radius: an Org A key compromise affects every counterparty pinned to that key, not the entire ecosystem. Each counterparty rotates on its own schedule.
  • Audit clarity: every cross-org record names the two kernels involved. An auditor checking a receipt knows exactly which two operators' policies applied.

Worked example: Org A and Org B

Org A runs a research kernel; Org B runs a partner kernel hosting domain-specific tools. They want one of A's agents to call B's billing.read tool with a budget of USD 50.00.

1. Exchange kernel keys out of band

Each operator publishes its kernel signing public key through a channel both sides already trust (signed announcement, secure email, ticket attached to a procurement record). The other side installs the key as a trust anchor:

rust
// Org A configuring Org B as a trust anchor.
let exchange_a = KernelTrustExchange::new("org-a-kernel", org_a_keypair.clone())
    .with_trusted_peer("org-b-kernel", org_b_public_key.clone());

// Org B configuring Org A as a trust anchor.
let exchange_b = KernelTrustExchange::new("org-b-kernel", org_b_keypair.clone())
    .with_trusted_peer("org-a-kernel", org_a_public_key.clone());

2. Run the handshake

Each side builds a signed envelope addressed to the other and sends it over an attested transport (mTLS RPC in production). Each side verifies and pins:

rust
let now = unix_seconds_now();
let envelope_a_to_b = exchange_a.local_envelope("org-b-kernel", "nonce-1", now)?;
let envelope_b_to_a = exchange_b.local_envelope("org-a-kernel", "nonce-2", now)?;

// Org B receives A's envelope and pins.
let peer_a_at_b = exchange_b.accept_envelope(&envelope_a_to_b, "org-a-kernel", now)?;

// Org A receives B's envelope and pins.
let peer_b_at_a = exchange_a.accept_envelope(&envelope_b_to_a, "org-b-kernel", now)?;

3. Install pinned peers on the kernel

rust
let kernel_a = ChioKernel::new(config_a)
    .with_federation_peers(vec![peer_b_at_a]);
kernel_a.set_federation_local_kernel_id("org-a-kernel");

let kernel_b = ChioKernel::new(config_b)
    .with_federation_peers(vec![peer_a_at_b]);
kernel_b.set_federation_local_kernel_id("org-b-kernel");

4. Store the federation policy

Both sides record their federation admission policy on the local trust control plane. The record is a FederationAdmissionPolicyRecord wrapping a signed FederatedOpenAdmissionPolicyArtifact (the same fields documented above); upsert reads it from --input and mirrors it into the local --federation-policies-file registry.

bash
$ chio trust federation-policy upsert \
    --input ./org-a-to-org-b.json \
    --federation-policies-file ./federation-policies.json
org-a-to-org-b.jsonjson
{
  "schema": "chio.permissionless-federation-policy.v1",
  "publishedAt": 1714291200,
  "policy": {
    "body": {
      "schema": "chio.federation-open-admission-policy.v1",
      "policyId": "fap-org-a-to-org-b-001",
      "issuedAt": 1714291200,
      "namespace": "billing.org-b.internal",
      "governingOperatorId": "org-a",
      "allowedAdmissionClasses": ["bond_backed"],
      "stakeRequirements": [
        {
          "admissionClass": "bond_backed",
          "requiredBondClass": "listing",
          "minimumBondAmount": { "units": 5000, "currency": "USD" },
          "slashable": true,
          "governanceCaseRequired": true
        }
      ],
      "governingCharterRef": {
        "kind": "governance_charter",
        "schema": "chio.registry.governance-charter.v1",
        "artifactId": "chr-org-a-2026-001",
        "operatorId": "org-a",
        "sha256": "<64 hex: sha256 of the charter artifact>"
      },
      "feeScheduleRef": {
        "kind": "open_market_fee_schedule",
        "schema": "chio.registry.market-fee-schedule.v1",
        "artifactId": "fee-org-a-2026-001",
        "operatorId": "org-a",
        "sha256": "<64 hex: sha256 of the fee-schedule artifact>"
      },
      "explicitLocalReviewRequired": true,
      "visibilityOnlyWithoutActivation": true
    },
    "signerKey": "<64 hex: the signing operator's Ed25519 public key>",
    "signature": "<128 hex: Ed25519 over the canonical JSON of body>"
  }
}

5. Issue the cross-org capability

An authority at Org A calls POST /v1/federation/capabilities/issue with a delegation policy that caps scope to billing.read on billing.org-b.internal with a USD 50.00 ceiling. Trust-control mints the child capability, persists the delegation anchor and child snapshot, and returns both ids.

6. Dispatch the tool call

The agent at Org A presents the child capability to Org B's tool. Org B's kernel verifies the capability against the pinned FederationPeer key, applies its stored admission policy (allowed_admission_classes and any per-pair activation scope, delegation, and import controls), invokes the tool, and produces a receipt. The receipt is co-signed by both kernels (see Bilateral Receipts).

rendering
Two kernels exchange PeerHandshakeEnvelopes, pin each other as a FederationPeer, and record an admission policy at each trust control plane before a cross-org capability is issued. The tool dispatch and the co-signature that follow issuance are not drawn.
sourcecrates/trust/chio-federation/src/trust_establishment.rs:706-836crates/platform/chio-control-plane/src/trust_control/service_types/paths.rs:12-19at fe56570

Error cases

The handshake failures are the 16 variants of PeerHandshakeError. Each one carries the exact reason string it prints, and each is fail-closed: a caller refuses to pin a peer when any step fails.

crates/trust/chio-federation/src/trust_establishment.rs462-528rust
/// Errors raised by the trust-establishment primitives. Every variant is
/// fail-closed: callers MUST refuse to pin a peer when any step fails.
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
pub enum PeerHandshakeError {
    #[error("unsupported handshake schema: {0}")]
    UnsupportedSchema(String),

    #[error("canonical JSON encoding failed: {0}")]
    CanonicalJson(String),

    #[error("handshake signing failed: {0}")]
    SigningFailed(String),

    #[error("remote handshake signature is invalid")]
    InvalidSignature,

    #[error("capability negotiation failed closed: {0}")]
    CapabilityNegotiation(String),

    #[error("remote envelope is addressed to kernel_id {addressed_to} but we are {actual}")]
    AddressMismatch {
        addressed_to: String,
        actual: String,
    },

    #[error("remote envelope declares self as kernel_id {declared} but we expected {expected}")]
    KernelIdMismatch { declared: String, expected: String },

    #[error("remote envelope timestamp {envelope} drifts from local clock {local} beyond {skew}s")]
    ClockSkewExceeded {
        envelope: u64,
        local: u64,
        skew: u64,
    },

    #[error("peer {0} is not pinned; run a handshake before resolving")]
    PeerNotPinned(String),

    #[error("peer {0} is stale and must be re-handshaked before use")]
    PeerStale(String),

    #[error("peer {0} is not trusted for first contact; configure a trust anchor before accepting handshakes")]
    MissingTrustAnchor(String),

    #[error("peer {kernel_id} declared unexpected public key; expected {expected}, got {actual}")]
    UnexpectedPeerKey {
        kernel_id: String,
        expected: String,
        actual: String,
    },

    #[error("peer {kernel_id} conformance tier {actual:?} is below required {minimum:?}")]
    ConformanceTierBelowMinimum {
        kernel_id: String,
        actual: ConformanceTier,
        minimum: ConformanceTier,
    },

    #[error("invalid conformance evidence: {0}")]
    InvalidConformanceEvidence(String),

    #[error("invalid ladder manifest reference: {0}")]
    InvalidLadderManifestRef(String),

    #[error("trust store is poisoned and cannot service requests")]
    StorePoisoned,
}

These are the ones a bare retry does not clear, so an operator acts on them rather than logging them:

VariantOperator action
MissingTrustAnchorFirst contact with no prior with_trusted_peer install. Install the anchor out of band, then retry.
UnexpectedPeerKeyThe declared key differs from the anchor or the already-pinned key. The variant carries both the expected and the actual hex. Re-pinning takes explicit operator action.
ClockSkewExceededThe envelope timestamp is further from the local clock than max_handshake_skew_secs. Check NTP on both kernels and re-issue the envelope.
PeerStale and PeerNotPinnedresolve(kernel_id, now) found a pin past rotation_due, or no pin at all (trust_establishment.rs:839). Run the handshake again.
ConformanceTierBelowMinimumThe peer's negotiated tier is below the quorum policy's min_tier. Raise the peer's tier or lower the local floor.
StorePoisonedThe peer trust store lock is poisoned after an earlier panic. Restart the affected service.

Trust-control issuance has its own failure case beyond the handshake:

  • Untrusted delegation-policy signer: a federated issuance carrying a delegation policy whose signer is not in the local trusted issuer set is rejected at POST /v1/federation/capabilities/issue (see spec/WIRE_PROTOCOL.md §4.2).

Federated receipt tables

Imported evidence and cross-org lineage land in three SQLite tables created inline by chio-store-sqlite/src/receipt_store/bootstrap/open.rs. The schemas (lines 1412-1449):

crates/platform/chio-store-sqlite/src/receipt_store/bootstrap/open.rssql
CREATE TABLE IF NOT EXISTS federated_lineage_bridges (
    local_capability_id TEXT PRIMARY KEY
        REFERENCES capability_lineage(capability_id) ON DELETE CASCADE,
    parent_capability_id TEXT NOT NULL,
    share_id TEXT REFERENCES federated_evidence_shares(share_id)
);
CREATE INDEX IF NOT EXISTS idx_federated_lineage_bridges_parent
    ON federated_lineage_bridges(parent_capability_id);

CREATE TABLE IF NOT EXISTS federated_evidence_shares (
    share_id TEXT PRIMARY KEY,
    manifest_hash TEXT NOT NULL,
    imported_at INTEGER NOT NULL,
    exported_at INTEGER NOT NULL,
    issuer TEXT NOT NULL,
    partner TEXT NOT NULL,
    signer_public_key TEXT NOT NULL,
    require_proofs INTEGER NOT NULL DEFAULT 0,
    query_json TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_federated_evidence_shares_imported_at
    ON federated_evidence_shares(imported_at);

CREATE TABLE IF NOT EXISTS federated_share_tool_receipts (
    share_id TEXT NOT NULL
        REFERENCES federated_evidence_shares(share_id) ON DELETE CASCADE,
    seq INTEGER NOT NULL,
    receipt_id TEXT NOT NULL,
    timestamp INTEGER NOT NULL,
    capability_id TEXT NOT NULL,
    subject_key TEXT,
    issuer_key TEXT,
    raw_json TEXT NOT NULL,
    PRIMARY KEY (share_id, seq),
    UNIQUE (share_id, receipt_id)
);
CREATE INDEX IF NOT EXISTS idx_federated_share_receipts_capability
    ON federated_share_tool_receipts(capability_id);
CREATE INDEX IF NOT EXISTS idx_federated_share_receipts_subject
    ON federated_share_tool_receipts(subject_key);
  • federated_evidence_shares records each accepted import with issuer, partner, signer key, and the canonical query that produced it.
  • federated_share_tool_receipts stores raw imported receipt JSON keyed by (share_id, seq); (share_id, receipt_id) is uniquely indexed so duplicate imports are idempotent.
  • federated_lineage_bridges links a locally-minted delegation anchor (in capability_lineage) to its imported parent and the share that brought the parent across. ON DELETE CASCADE on the local capability id means deleting the local anchor drops the bridge row, never the imported share.

In the procurement tour

This is station 4 of the Procurement Tour: the buyer kernel resolves Vanguard as a pinned federation peer before sending the call. The handshake itself completed earlier; this station is the runtime check.

Picks up from previous station. The buyer holds a GovernedTransactionIntent targeting vanguard-security with a quoted, hold-capture settlement.

Lattice and Vanguard ran a bilateral handshake at onboarding; each kernel pinned the other's key as a FederationPeer with a 12-hour rotation window. At dispatch time the buyer kernel calls KernelTrustExchange::resolve(remote_kernel_id, now); the call returns the pinned record and asserts freshness via FederationPeer::is_fresh(now):

The record it gets back is a FederationPeer whose three defaulted fields are absent from the wire when the peer left them at their defaults. Illustrative values in real field names:

json
{
  "kernelId": "did:chio:vanguard-security",
  "publicKey": "<64 hex: Vanguard's Ed25519 kernel signing key>",
  "establishedAt": 1745784000,
  "rotationDue": 1745827200
}

The pin is fresh (now < rotationDue), so the buyer kernel proceeds. The resolved public key is the verification anchor that station 5 uses to check Vanguard's detached signature on the dual-signed receipt; on a stale pin resolve returns PeerStale and the call is refused until a re-handshake. What the two operators agreed beyond the pin lives in the signed activation exchange described above: FederationTrustScope for namespace and actor kinds, FederationDelegationControl for hop count and attenuation, and FederationImportControl for what an import may do locally.

Continue at next station, where the tool runs and both kernels co-sign the same receipt body.