Chio/Docs

Portable Reputation

Present signed operating history across organizations while allowing each receiver to calculate reputation under its own policy.

Concept chio@5f63e6e

On this page

When a provider agent arrives from another organization, the receiver scores the signed history the agent carries under the receiver’s own policy. That imported score sits beside the receiver’s own observations with its provenance, and it informs the grant decision while granting nothing itself.

The example follows one agent from Org A to Org B. Org B already has a bilateral policy with Org A and has pinned Org A’s kernel as a federation peer.

Evidence crosses the boundary; the score is computed at the receiver

The agent carries a passport with Merkle roots over its receipt log at Org A. Org B fetches inclusion proofs from that log, checks them, and projects an imported score that it never merges into its native one.

Imported reputationChoose what arrives.
Org AOrg Bsignspassport · Merkle rootsinclusion proofsproofissuerage× 0.50ρK′aKinreceipt logOrg A kernelagentOrg B kernelimported0.40nativeno receipts yetOrg AOrg Bpassportinclusion proofsproofissuerage× 0.50ρK′aKinreceipt logOrg A kernelagentOrg B kernelimported0.40nativeno receipts yet

Org B scores the import and keeps it beside its own record

Org B checks each inclusion proof against a root in the passport, keeps receipts whose signer is in trusted_issuers, and projects 0.80 × 0.50 = 0.40 under the default attenuation. The native projection stays empty until Org B’s kernel signs receipts of its own. Bilateral Receipts.

One agent’s history moving from Org A to Org B: the passport’s Merkle roots, the inclusion proofs fetched from Org A’s receipt log, the three import checks, and the two projections Org B keeps apart. The 0.80 score is illustrative; the operator’s grant decision is left out.

Under the default attenuation factor of 0.50, an eligible imported input of 0.80 contributes 0.40, and inputs past 30 days expire. For a new arrival, Org B has signed no receipts about the subject, so the native projection is empty, and the imported evidence does not fill it. Both projections reach the operator with their provenance, and the operator decides whether to issue, narrow, or withhold authority.

Financial claims travel in the same carrier, and an imported financial credential reads as asserted after its signature verifies.

Read more in Agent Passports and Financial Credentials.

The agent owns its key; each organization owns its score

Reputation in Chio is a score an organization computes from signed receipts associated with a subject keypair. Three properties follow:

  • Identity is the keypair. A did:chio:<public-key> identifier encodes the public key, so any verifier that learns the DID checks signatures by that key without contacting an identity provider.
  • Evidence binds the subject. The receipt’s capability and its signed actor attribution resolve to the subject. The kernel signing key identifies the recorder, and the agent’s identity is its own key.
  • Reputation is a projection. Each organization computes a score from the receipts it admitted, weighted by its own policy, so organizations can reach different conclusions from the same Agent Passport.

An organization stores the receipts its kernel signed at runtime. Receipts from other organizations arrive as imported evidence shares, described in Bilateral Receipts.

What an Agent Passport carries

An Agent Passport carries the subject’s receipt roots, the issuing operator’s attestation of reputation signals, and optional enterprise identity provenance; Agent Passports gives the full schema. Its SD-JWT VC projection always discloses iss, sub, vct, cnf, chio_passport_id, chio_subject_did, and chio_credential_count. It discloses chio_issuer_dids, chio_merkle_roots, and chio_enterprise_identity_provenance selectively, and an optional chio_passport_status sidecar points at the issuer’s lifecycle endpoint.

A passport can carry credentials from several organizations. The bounded CrossIssuerPortfolio profile embeds one AgentPassport per entry, each tagged Native, Imported, or Migrated, so a verifier checks each entry independently. Its migrations ledger of signed SignedCrossIssuerMigration records preserves subject-identity continuity when an agent moves across issuers; each record carries from_issuer, to_issuer, from_subject, to_subject, and prior_passport_ids. The profile preserves evidence and creates no new trust root.

Imported shares stay attenuated and widen no runtime authority

Native reputation comes from receipts the local kernel signed: dispatched calls, denials, budget draws, and settlement outcomes. Imported reputation comes from receipts and reputation summaries in signed evidence shares from a federation peer, weighted by the bilateral policy. The comparison tools show both values with provenance, and the kernel uses no combined value for runtime enforcement.

  • Provenance. Each share records share_id, issuer, partner, signer_public_key, imported_at, and exported_at, persisted in federated_evidence_shares.
  • Policy echo. The bilateral FederationImportControl in effect at import is recorded with the share, so an auditor sees which guardrails applied.
  • Conservative defaults. Proofless shares are rejected; a share whose age past exported_at exceeds max_signal_age_days (default 30 days) expires; an accepted share contributes an attenuatedCompositeScore in place of a native confidence number.
  • Visibility only. Imported evidence informs visibility and reputation views. The default FederationImportControl sets prohibit_ambient_runtime_admission = true.

Inclusion proofs keep an import small and tamper evident

A passport names receipt-log Merkle roots for checkpointed evidence. The verifier checks inclusion against an authenticated root, then checks the receipt signature and its subject and request bindings on their own. Evidence gains checkpoint coverage only from a checkpoint, never from appearing in a credential.

Two consequences follow. A passport stays small when the agent has thousands of receipts on file, because the verifier pulls only the proofs it needs. And an inclusion proof against a signed root is binary: the receipt was logged at the issuer when the root was published, or it was not.

portable-reputation · did-resolvetranscript
$ chio did resolve \
    --did did:chio:bff663535a5cf58658cc38595d20dc4501f6dfc076ddf07e20571d413a3ceb5a
{
  "@context": "https://www.w3.org/ns/did/v1",
  "id": "did:chio:bff663535a5cf58658cc38595d20dc4501f6dfc076ddf07e20571d413a3ceb5a",
  "verificationMethod": [
    {
      "id": "did:chio:bff663535a5cf58658cc38595d20dc4501f6dfc076ddf07e20571d413a3ceb5a#key-1",
      "type": "Ed25519VerificationKey2020",
      "controller": "did:chio:bff663535a5cf58658cc38595d20dc4501f6dfc076ddf07e20571d413a3ceb5a",
      "publicKeyMultibase": "z6MksNbpfH3b8boFk9zSgKhTKcBqxyYYjHXuQKtNQ6wj8E6m"
    }
  ],
  "authentication": [
    "did:chio:bff663535a5cf58658cc38595d20dc4501f6dfc076ddf07e20571d413a3ceb5a#key-1"
  ],
  "assertionMethod": [
    "did:chio:bff663535a5cf58658cc38595d20dc4501f6dfc076ddf07e20571d413a3ceb5a#key-1"
  ]
}
exit 0

The resolved document carries one Ed25519VerificationKey2020 method, the key the identifier is made of, as a multibase string. The receipt log appears as the optional ChioReceiptLogService entry; Org B discovers its URL there, pulls inclusion proofs, and validates them against the roots embedded in the passport before any projection runs.

Five steps take a provider agent from passport to grant decision

Org B is considering a capability for a provider agent that previously worked under Org A. The agent presents its passport at Org B’s door.

  1. Verify the passport. Org B’s verifier checks each native credential signature, or the chosen projected envelope, against its trusted issuer key. It confirms chio_subject_did matches the keypair the agent presented and consults the lifecycle sidecar; any status other than active fails closed.
  2. Pull and verify receipt roots. Org B fetches inclusion proofs from Org A’s ChioReceiptLogService endpoint, declared in Org A’s DID document, and verifies each proof against the root in the passport.
  3. Check issuers against trusted_issuers. Receipts signed by an Org A kernel key outside Org B’s bilateral trusted_issuers set are dropped. The rest form the imported corpus.
  4. Compute reputation. Org B projects imported reputation over the accepted corpus with the attenuation factor its bilateral policy declares, and native reputation over receipts its own kernel signed for the subject.
  5. Decide. The comparison view shows both projections with provenance. The operator chooses whether to issue the capability and with what scope, budget, and autonomy tier. Native receipts accumulate from the first invocation.

A passport without a live credential stops before any score

The comparison refuses before it projects anything. A passport with no credentials, and a passport whose credential has aged out, both stop at the credential check instead of resolving to a low score:

portable-reputation · compare-no-credentialtranscript
$ chio --json --receipt-db ./receipts.db reputation compare \
    --subject-public-key bff663535a5cf58658cc38595d20dc4501f6dfc076ddf07e20571d413a3ceb5a \
    --passport ./no-credentials.json
{"code":"urn:chio:error:trust:passport-empty","message":"the passport carries no credential","context":{"domain":"trust","severity":"error","stability":"stable","string_code":"CHIO-TRUST-PASSPORT-EMPTY"},"suggested_fix":"create the passport from receipts with chio passport create, which writes at least one credential"}
exit 1
portable-reputation · compare-expiredtranscript
$ chio --json --receipt-db ./receipts.db reputation compare \
    --subject-public-key bff663535a5cf58658cc38595d20dc4501f6dfc076ddf07e20571d413a3ceb5a \
    --passport ./agent-passport.json
{"code":"urn:chio:error:trust:credential-expired","message":"the passport credential has expired","context":{"domain":"trust","severity":"error","stability":"stable","string_code":"CHIO-TRUST-CREDENTIAL-EXPIRED"},"suggested_fix":"issue a fresh passport with chio passport create, then compare again"}
exit 1

--subject-public-key takes a bare 64-character hex Ed25519 key. A Chio Ed25519 key carries no ed25519: prefix: PublicKey::to_hex emits bare hex for Ed25519 and reserves a prefix for the other curves.

Each import failure ends in a defined state

Org B’s import path fails closed on missing evidence and keeps every accepted share idempotent.

FailureConditionBehavior
Stale evidenceShare past max_signal_age_days (default 30 days)Share rejected; its contribution drops from the projection
Revoked credentialStatus sidecar reports revokedVerifier fails closed; receipts under the credential are excluded
Conflicting attestationsTwo issuers sign contradictory signals about one subjectComparison view shows both with provenance; the operator decides
Unknown issuer keyReceipt signed by a key outside trusted_issuersReceipt dropped at import; share marked partial
Proofless shareNo Merkle inclusion proofs for referenced receiptsRejected when require_proofs = true in the partner record
ReplaySame share imported twiceIdempotent: the share_id primary key keeps one row

Next: see how the native score is computed