EconomyReputation & Identity
Agent Passports
Reference for Agent Passport schemas, credential projections, OpenID flows, and offline verification.
did:chio Identifiers
Every Agent Passport subject 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. Because the identifier embeds the key, a verifier can check signatures without a registry lookup, DID resolver, or 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 Agent 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 Agent Passport itself carries no signature. Signature verification applies to 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 |
Passport v2 also carries financial credentials
chio.agent-passport.v2) adds a family of signed, individually verifiable, selectively disclosable financial credentials (chio.fincred.*) that carry an agent's economic record across organizations, documented at Portable Financial Credentials. They are distinct from the identity passport described here.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
OID4VCI and OID4VP Protocols
The SD-JWT VC projection supports two OpenID-family protocols: OID4VCI for issuance and a limited OID4VP path for presentation. Both operate over the same projected credential, so a holder issued through OID4VCI can present through OID4VP without a second encoding step.
OID4VCI Issuance
An Agent Passport is issuable over OpenID for Verifiable Credential Issuance. The credential configuration id is chio_agent_passport, the credential format is chio-agent-passport+json, and issuer metadata is served at /.well-known/openid-credential-issuer. The pre-authorized-code grant drives the offer, token, and credential exchange, exposed through the chio passport issuance metadata|offer|token|credential CLI verbs.
pub const OID4VCI_PRE_AUTHORIZED_GRANT_TYPE: &str =
"urn:ietf:params:oauth:grant-type:pre-authorized_code";
pub const CHIO_PASSPORT_OID4VCI_CREDENTIAL_CONFIGURATION_ID: &str = "chio_agent_passport";
pub const CHIO_PASSPORT_OID4VCI_FORMAT: &str = "chio-agent-passport+json";
pub const OID4VCI_ISSUER_METADATA_PATH: &str = "/.well-known/openid-credential-issuer";OID4VP Presentation
Presentation supports a limited OID4VP verifier flow over the projected application/dc+sd-jwt Agent Passport presentation endpoint. It does not implement generic OID4VP. A request carries a DCQL query for exactly one credential, and the verifier rejects any credential whose format is not application/dc+sd-jwt or whose type is not the chio-passport SD-JWT VC type. Verifier metadata is served at /.well-known/chio-oid4vp-verifier, and the chio passport oid4vp verbs drive the exchange.
impl Oid4vpDcqlQuery {
pub fn validate(&self) -> Result<(), CredentialError> {
if self.credentials.len() != 1 {
return Err(CredentialError::InvalidOid4vpRequest(
"Chio OID4VP currently supports exactly one requested credential".to_string(),
));
}
self.credentials[0].validate()
}
}HTTP Flow
Both protocols use a fixed external HTTP flow that a raw client can drive without the Chio CLI: issuance covers the first four calls, presentation the rest. A holder issued a credential in steps one through four presents it back through either the OID4VP lane (steps five through seven) or the Chio-native challenge lane (steps eight and nine).
| Step | Endpoint | Purpose |
|---|---|---|
| 1 | GET /.well-known/openid-credential-issuer | Fetch issuer metadata. |
| 2 | GET /.well-known/jwks.json, GET /.well-known/chio-passport-sd-jwt-vc or .../chio-passport-jwt-vc-json | Optional. Portable issuer key material and projected-profile type metadata. Omitted from issuer metadata and served as 404 when no portable signing key is configured. |
| 3 | POST /v1/passport/issuance/token | Redeem a pre-authorized code for an access token. |
| 4 | POST /v1/passport/issuance/credential | Redeem a native AgentPassport or a projected application/dc+sd-jwt or jwt_vc_json credential. |
| 5 | GET /.well-known/chio-oid4vp-verifier | Fetch verifier metadata. |
| 6 | GET /v1/public/passport/oid4vp/requests/{request_id} | Fetch the signed OID4VP request object, or resolve the same transaction through the HTTPS cross-device launch URL the verifier returns. |
| 7 | POST /v1/public/passport/oid4vp/direct-post | Submit the signed direct_post.jwt holder response. |
| 8 | GET /v1/public/passport/challenges/{challenge_id} | Fetch a stored Chio-native verifier challenge. |
| 9 | POST /v1/public/passport/challenges/verify | Submit the signed Chio-native holder response. |
The OID4VP request object pins client_id_scheme=redirect_uri, response_type=vp_token, and response_mode=direct_post.jwt. Admin operations (issuance offers, challenge creation, verifier-policy CRUD, lifecycle publish and revoke) stay on separate routes so public transport never widens verifier admin authority.
Multi-Issuer Composition
An Agent 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 Agent Passport without either issuer needing to coordinate with the other.
This works because the Agent Passport is a container: each credential carries its own Ed25519 signature, 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 issuer: Option<String>, // single-issuer back-compat field
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/passport.rs) constrains each credential independently. It can pin issuers to an issuer_allowlist, set a min_receipt_count or min_composite_score per credential, and require an active Agent Passport lifecycle before accepting the Agent Passport.
Offline Verification
The portable kernel core ships an offline-capable Agent 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 verification component that browsers and edge adapters can run with the same Ed25519 path as the sidecar.
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
- 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