Spec Blog Products Services Contact Follow the Build
Draft Spec · Phase 2

Passport

Created: 2026-04-01  ·  Status: DRAFT  ·  Builds on: Phase 1 — Identity Layer
Phase 1 — Identity Phase 2 — Passport Phase 3 — Registry Phase 4 — Distribution

What This Is

A working spec for the agent Passport layer. This builds directly on Phase 1 (Identity Layer) — read that spec first.

The Passport answers a different question than identity. Identity says who an agent is. Passport says what an agent can do — and critically, who vouches for it.

The Core Problem

An agent with a verified identity (AgentID) can prove it's itself. That's Phase 1. But in a multi-agent system, "who are you?" is only the first question. The second question — asked by every agent deciding whether to delegate work — is:

What can you actually do, and should I trust those claims?

Right now there's no standard way to answer that. Agents make informal capability claims in their system prompts, or through out-of-band documentation, or not at all. There's no machine-readable format, no attestation mechanism, and no way to verify claims against a trusted source.

This creates problems:

The Passport layer fixes this. It's the credential layer of the A2A infrastructure stack.

What Is an Agent Passport?

An Agent Passport is a signed, time-bounded document that attests: this identity has these capabilities, as verified by this issuer.

Key properties:

What the Passport layer is NOT

Passport Record Structure

{
  "id": "pass_01HZ...",
  "version": 1,
  "created_at": "2026-04-01T06:00:00Z",
  "expires_at": "2026-07-01T00:00:00Z",

  "subject": {
    "agent_id": "agnt_01HZ...",
    "fingerprint": "sha256:<hex>"
  },

  "issuer": {
    "type": "self | operator | third_party",
    "id": "string — issuer identifier",
    "name": "string — human-readable name",
    "public_key": "base64 Ed25519 public key",
    "fingerprint": "sha256:<hex>"
  },

  "capabilities": [
    {
      "token": "email:send",
      "label": "Send Email",
      "scope": "transactional_only",
      "constraints": {},
      "attested_at": "2026-04-01T06:00:00Z"
    }
  ],

  "attestation_context": {
    "method": "operator_assertion | automated_test | third_party_audit",
    "evidence_url": "optional link to evidence",
    "notes": "optional freeform"
  },

  "signature": "base64 — issuer signature over canonical JSON"
}

Capability Token Format

Capability tokens are structured strings:

<domain>:<action>[:<qualifier>]

Examples:

calendar:read
calendar:write
email:send
email:send:transactional_only
data:phi:access
data:phi:access:read_only
payment:process
agent:delegate
agent:spawn
tool:web_search
tool:code_execution
tool:file_read
tool:file_write

# Operator-namespaced custom tokens:
custom:acme_corp:crm_write

Token namespaces: calendar:, email:, data:, payment:, agent:, tool:, domain:, custom:<operator_id>:

Unknown tokens are treated as "not attested" — not errors. The canonical token list grows via RFC process.

Issuer Types and Trust

Issuer Type Who Signs Trust Level Use Case
self The agent itself Low Development, initial deployment
operator The deploying operator Medium Production deployments, internal agent networks
third_party Independent auditor or certification body High Regulated industries, public-facing networks

Trust policy is the peer's responsibility. The Passport layer provides the primitives; it doesn't make trust decisions for you.

Passport Operations

// Issue a Passport
issue_passport(
  subject_agent_id: AgentID,
  capabilities: CapabilityToken[],
  issuer_private_key: bytes,
  issuer_info: IssuerInfo,
  ttl_days: number
) → Passport

// Verify a Passport
verify_passport(passport: Passport) → {
  valid: boolean,
  expired: boolean,
  revoked: boolean,
  errors: string[]
}

// Check a specific capability
has_capability(
  passport: Passport,
  token: CapabilityToken,
  scope?: string
) → boolean

// Revoke a Passport (issuer only)
revoke_passport(
  passport_id: string,
  issuer_private_key: bytes,
  reason: string
) → RevocationRecord

// Export / Import
export_passport(passport: Passport) → string
import_passport(string) → Passport

Passport Lifecycle

[Issue] → [Active] → [Expired]
             ↓
         [Revoked]

Recommended TTLs: self-issued 30 days · operator 90 days · third-party 1 year.

Renewal creates a new Passport with a new ID. The old Passport remains valid until its own expiry.

Multiple Passports (Passport Bundle)

An agent may hold multiple Passports simultaneously — expected and by design. Peers receive a Passport bundle:

{
  "agent_id": "agnt_01HZ...",
  "passports": [ ...Passport[] ]
}

Helper: best_passport_for(capability, min_issuer_type) — returns the highest-trust Passport that attests the requested capability.

Connection to Phase 1 (Identity)

The Passport is built on the identity layer:

A Passport without an underlying AgentID is invalid. Without identity, there's nothing to attach a Passport to.

Connection to Phase 3 (Registry)

Phase 3 Registry adds discovery, publication, and distributed revocation. Phase 2 Passport format is designed to be Registry-compatible — in Phase 2, Passport exchange is out-of-band (file share, A2A, etc.). Phase 3 makes this automatic.

Open Questions

Q1: Capability token namespace governance

Lean: Start with a tight opinionated core (~30 tokens across 7 namespaces). Operator-namespaced custom:<id>: for everything else. Grow core namespace via RFC process.

Q2: Offline revocation in Phase 2

Lean: No online revocation in Phase 2. Short TTLs compensate. Issuers distribute revocation records out-of-band. Phase 3 Registry adds real distributed revocation.

Q3: Capability constraints

Lean: Keep the constraints field, but treat it as opaque. The Passport layer carries and signs constraints; it doesn't interpret them. Standardization of constraint semantics is future work.

Q4: Passport bundle as first-class type

Lean: Yes — define PassportBundle { agent_id, passports: Passport[] } as an explicit type. The bundle is the primary exchange unit; making it explicit enables validation that all Passports reference the same agent_id.

Q5: Cross-issuer capability composition

Decision: Out of scope for the Passport layer. Composition policy is the peer's responsibility. The layer provides individual capability checks per Passport; peers decide whether to AND, OR, or require specific issuer combinations.

Success Criteria for Phase 2

  1. An operator can issue a Passport for an agent (operator-signed)
  2. An agent can self-issue a Passport
  3. A peer can verify a Passport and check for a specific capability
  4. Passports expire correctly based on expires_at
  5. An issuer can revoke a Passport; peers with the revocation record correctly reject it
  6. PassportBundle validates correctly (all Passports reference same agent_id)
  7. Passport records round-trip losslessly JSON ↔ binary
  8. Core capability token set defined (≥20 tokens, ≥5 namespaces)
  9. Design questions Q1–Q5 have explicit decisions recorded
  10. Library ships with >90% test coverage
  11. Phase 3 (Registry) can start without revisiting Phase 2 design