Agent Passports
Reference for the data structures and verification mechanics behind Chio's portable identity layer. The companion how-to guide walks through producing and presenting a passport in practice; this page covers the schema, the standards-native projections, and the offline verification path that ships in the portable kernel core.
did:chio Identifiers
Every subject in a passport is a did:chio identifier:
did:chio:{64-lowercase-hex-Ed25519-public-key}The method-specific identifier is the lowercase hex form of an Ed25519 public key. Resolution is self-certifying: the public key is embedded in the identifier itself, so a verifier can check signatures with no registry lookup, no DID resolver, and no network call. Parsing rules in chio-did:
- The string must start with
did:chio:. - The suffix must be exactly 64 hexadecimal characters.
- The decoded public key must be Ed25519. P-256 and other algorithms are rejected with
DidError::UnsupportedKeyAlgorithm.
Resolution returns a W3C-compliant DID document with the embedded Ed25519 verification method (in multibase encoding) plus optional service endpoints:
pub const RECEIPT_LOG_SERVICE_TYPE: &str = "ChioReceiptLogService";
pub const PASSPORT_STATUS_SERVICE_TYPE: &str = "ChioPassportStatusService";Service endpoints are attached by the resolving environment, not the identifier itself. Two operators resolving the same did:chio can hand back different service URLs while sharing the same verification method.
Passport Schema
The native passport (schema tag chio.agent-passport.v1) is an unsigned bundle of independently verifiable credentials:
pub struct AgentPassport {
pub schema: String, // chio.agent-passport.v1
pub subject: String, // did:chio of the agent
pub credentials: Vec<ReputationCredential>,
pub merkle_roots: Vec<String>, // receipt-log checkpoint roots
pub enterprise_identity_provenance: Vec<EnterpriseIdentityProvenance>,
pub issued_at: String, // RFC 3339
pub valid_until: String, // RFC 3339
pub trust_tier: Option<TrustTier>, // optional, recent addition
}The passport itself carries no signature. Trust comes from the credentials inside it: each ReputationCredential is independently signed by an issuer, and verification walks the bundle credential by credential.
The four field groups serve different verification needs:
| Field | Purpose |
|---|---|
subject | Binds the passport to a single Ed25519 keypair via did:chio |
credentials | Issuer-signed reputation attestations carrying scorecards |
merkle_roots | Receipt-log checkpoint roots so a verifier can spot-check receipt evidence |
enterprise_identity_provenance | Federation evidence: which IdP authenticated the principal that issued each credential |
Verifiable Credential Projections
Chio supports three wire formats for a passport. The native format is the source of truth; the other two are projections derived from it for interop with W3C Verifiable Credentials tooling.
| Format | Where it lives | Use case |
|---|---|---|
| Native CHIO JSON | chio-credentials/src/passport.rs | Source of truth. All other formats are derived from this. |
| SD-JWT VC | portable_sd_jwt.rs | IETF SD-JWT-VC. Holders selectively disclose individual claims. |
| JWT VC JSON | portable_jwt_vc.rs | W3C VC 2.0 in JWT-encoded JSON for VP-style flows. |
The SD-JWT VC projection partitions claims into two groups: always-disclosed claims that travel in cleartext, and selectively disclosable claims that the holder reveals on demand.
| Always disclosed | Why |
|---|---|
iss | The credential issuer (the issuing operator) |
sub | Holder thumbprint (binds to the holder's key) |
vct | Verifiable Credential type (the chio-passport SD-JWT VC type) |
cnf | Confirmation key (holder JWK for DPoP-style binding) |
chio_passport_id | Stable passport identifier |
chio_subject_did | did:chio of the agent the passport binds to |
chio_credential_count | Number of credentials inside the bundled passport |
| Selectively disclosable | Why |
|---|---|
chio_issuer_dids | List of issuer did:chios for the credentials in the bundle |
chio_merkle_roots | Receipt-log checkpoint roots referenced by the credentials |
chio_enterprise_identity_provenance | Federation evidence (IdP, principal, tenant, groups, roles) |
Selective disclosure is a presentation concern
Multi-Issuer Composition
A passport can carry credentials from any number of issuers. Two organizations can each independently sign a credential for the same agent, and the agent bundles both into a single passport without either issuer needing to coordinate with the other.
This works because the passport is just a container: each credential carries its own Ed25519 proof, and verification walks the credentials individually. The PassportVerification result returned by verify_agent_passport exposes both lists:
pub struct PassportVerification {
pub passport_id: String,
pub subject: String,
pub issuers: Vec<String>, // unique issuer did:chios
pub issuer_count: usize,
pub credential_count: usize,
pub merkle_root_count: usize,
pub enterprise_identity_provenance: Vec<EnterpriseIdentityProvenance>,
pub passport_lifecycle: Option<PassportLifecycleResolution>,
pub verified_at: u64,
pub valid_until: String,
}A verifier policy (see PassportVerifierPolicy in chio-credentials/src/policy.rs) can require credentials from a specific issuer allowlist or set a minimum issuer count before accepting the passport.
Offline Verification (Phase 20.1)
The portable kernel core ships an offline-capable passport verifier at chio-kernel-core/src/passport_verify.rs. It is no_std + alloc, so the same verifier compiles into native sidecars, browser WASM, mobile runtimes, and edge proxies.
The portable verifier consumes a thin PortablePassportEnvelope (schema tag chio.portable-agent-passport.v1) that wraps canonical-JSON bytes of any passport projection:
pub struct PortablePassportBody {
pub schema: String, // chio.portable-agent-passport.v1
pub subject: String,
pub issuer: PublicKey,
pub issued_at: u64,
pub expires_at: u64,
pub payload_canonical_bytes: Vec<u8>, // hex-encoded on the wire
}
pub struct PortablePassportEnvelope {
pub body: PortablePassportBody,
pub signature: Signature,
}verify_passport performs four checks:
- The bytes parse as a
PortablePassportEnvelopeand the schema tag matches. - The issuer key is in the relying party's authority key set.
- The Ed25519 signature is valid over the canonical JSON of the body.
- The clock value sits in
[issued_at, expires_at).
On success it returns a VerifiedPassport with the subject, issuer, validity bounds, evaluation time, and the canonical payload bytes. There is no revocation lookup, no issuer-chain validation, and no payload decoding in the portable path. Those richer checks remain in the native chio-credentials / chio-kernel code; the portable core is the trust primitive that browsers and edge adapters can run with the same Ed25519 path the sidecar uses.
Holder Binding
A passport binds to runtime key material through the holder's confirmation key. In the SD-JWT VC projection the cnf claim carries a JWK for the holder's Ed25519 key (the same key embedded in chio_subject_did). The holder's thumbprint is the SD-JWT's sub, so the issuer signature attests that this passport may only be presented by the holder of the bound key.
At runtime, the same key signs DPoP proofs on the request side. A relying party that accepts a passport plus a DPoP proof has cross- bound evidence: the passport says "this scorecard belongs to the holder of did:chio:7b...", and the DPoP proof says "this request was signed by the same key".
Worked Example: Two-Issuer Passport
Agent did:chio:7b... has been operating across two orgs: Operator A (security tools) and Operator B (data tools). Each observes its own slice of receipts and signs an issuer-specific scorecard.
{
"schema": "chio.agent-passport.v1",
"subject": "did:chio:7b0f6f63...",
"credentials": [
{
"issuer": "did:chio:a1b2...",
"credentialSubject": {
"id": "did:chio:7b0f6f63...",
"metrics": { "reliability": { "score": { "state": "known", "value": 0.97 } } }
},
"evidence": { "receipt_count": 5400, "checkpoint_roots": ["sha256:..."] },
"proof": { "type": "Ed25519Signature2020", "proofValue": "..." }
},
{
"issuer": "did:chio:c3d4...",
"credentialSubject": {
"id": "did:chio:7b0f6f63...",
"metrics": { "reliability": { "score": { "state": "known", "value": 0.93 } } }
},
"evidence": { "receipt_count": 1820, "checkpoint_roots": ["sha256:..."] },
"proof": { "type": "Ed25519Signature2020", "proofValue": "..." }
}
],
"merkle_roots": ["sha256:roota...", "sha256:rootb..."],
"enterprise_identity_provenance": [
{ "provider_id": "operator-a-okta", "provider_kind": "okta", "principal": "agent-7b@org-a", ... },
{ "provider_id": "operator-b-azure", "provider_kind": "azure-ad", "principal": "svc-7b@org-b", ... }
],
"issued_at": "2026-04-20T00:00:00Z",
"valid_until": "2026-07-20T00:00:00Z"
}A relying party Org C verifies the passport offline:
- Parse the passport and confirm
subject == did:chio:7b0f6f63.... - For each credential, verify the Ed25519 proof against the issuer's embedded key (issuer is itself a did:chio, so the public key is in the identifier).
- Confirm the credential subject equals the passport subject.
- Apply Org C's
PassportVerifierPolicy: for example, require both Operator A and Operator B in the allowlist, requiremin_receipt_count = 1000per credential, and require active passport lifecycle.
Org C now has cross-issuer evidence about the agent without ever contacting Operator A or Operator B. The verification result lists both issuers and both provenance records, which Org C's downstream policy can attenuate independently.
How This Differs from the How-To Guide
The page at /docs/guides/agent-passport is task-oriented: it walks through creating a passport, presenting it, and writing a verifier policy. This page is a reference: it documents the schema, the projections, the selective-disclosure partitioning, the multi-issuer composition rules, and the portable-kernel offline verification path. Cross-link both directions when working through an integration.
Related Reading
- Agent Passport guide · producing and presenting a passport end to end
- Reputation Scoring · the scorecard that goes inside each credential
- Federation Overview · bilateral policies and import attenuation across operators
- Compliance Certificates · the per-session counterpart that anchors receipt-side evidence