The authorization layer for multi-agent AI systems. Like IAM, but for your agent graph.
Agents are delegating to other agents. Nobody's checking the chain.
When Agent A delegates to Agent B, and Agent B delegates to Agent C — how do you know what C was actually authorized to do? Right now, every major framework (LangGraph, CrewAI, AutoGen) answers this question with: trust by convention. No signed proof. No scope enforcement. No way to revoke mid-flight.
That's not authorization. That's hope.
[Python Orchestrator] signs delegation → [TypeScript Agent] verifies before executing
↓
ScopeError: requires [write:db:customers], granted [read:db:customers] ✅
agentpassport gives every agent a cryptographic identity, signs delegation at every hop, and enforces scope before the handler runs. Revoke a token by JTI and the agent stops cleanly — no process kill, no partial state.
Cross-SDK trust chain — Python orchestrator delegates to TypeScript agent:
git clone https://github.com/ceavinrufus/agentpassport
cd agentpassport
uv run python -m demo.run_demo━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
agentpassport DEMO — Cross-SDK Trust Chain
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Orchestrator did:key:z6MkskpV…pks2 (Python)
TS Agent did:key:z6MkoFDL…3TZf (TypeScript)
[STEP 1] Python signs delegation JWT
scope ['read:db:customers'] ttl 3600s
[STEP 2] Python → TS: queryCustomers → 200 ✅
Auth chain verified, capability executed
[STEP 3] Python → TS: writeCustomer → 403 🛡️
ScopeError: requires [write:db:customers], granted [read:db:customers]
[STEP 4] Python revokes delegation mid-scenario
jti revoked → same request fails → 403 🛡️
[STEP 5] Auth chain trace
hop 0 jti=d77dd09a… ✅
iss z6MkskpV… (orchestrator)
sub z6MkoFDL… (ts-agent)
scope ['read:db:customers']
exp 2026-05-12T10:22:48Z
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Ownership binding — domain + wallet binding, offline verification, revocation:
uv run python -m demo.binding_demo━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
agentpassport — Ownership Binding Demo
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[STEP 1] Generate agent identity
DID: did:key:z6Mkv4kj…
✅ Agent identity created
[STEP 2] Bind agent to domain 'agentpassport.fyi'
✅ Domain binding created
[STEP 3] Bind agent to Ethereum wallet
✅ Wallet binding created
[STEP 4] Assemble binding document
Document (publish at https://agentpassport.fyi/.well-known/agent-passport.json)
[STEP 5] Verify signatures offline
✅ Domain binding signature valid
✅ Wallet binding signature valid
✅ Tampered signature correctly rejected
✅ Expired binding correctly rejected
[STEP 6] Revoke wallet binding
✅ Wallet binding is now revoked
✅ Domain binding unaffected by wallet revocation
[STEP 7] Final document state
binding type=domain [active]
binding type=wallet [REVOKED]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
agentpassport.fyi publishes its own /.well-known/agent-passport.json — you can verify it right now:
$ agentpass identity verify-domain \
--did did:key:z6Mkh8UwkN88kwynM3mYke8yFXr9ax69jZKv2TCuwG7yPzbw \
--domain agentpassport.fyiOutput:
Checking https://agentpassport.fyi/.well-known/agent-passport.json ...
✓ Valid domain binding: 'agentpassport.fyi' claims did:key:z6Mkh8UwkN88kwynM3mYke8yFXr9ax69jZKv2TCuwG7yPzbw
# Python
pip install agentpassport
# TypeScript / JavaScript
npm install @agentpassport/core| Problem | Without agentpassport | With agentpassport |
|---|---|---|
| Agent authorization | Trust by convention | Cryptographic proof |
| Scope enforcement | Ad-hoc checks | Declared + verified before execution |
| Revocation | Kill the process | Soft-stop by JTI, mid-flight safe |
| Cross-language | Custom per integration | Wire-compatible out of the box |
Every agent has an Ed25519 keypair. Its public key becomes a W3C-standard did:key: DID — no central registry, verifiable by anyone.
from agentpassport import Agent
agent = Agent("my-agent")
print(agent.did) # did:key:z6Mk...Trust flows through a chain of signed JWTs. Each hop narrows scope — an agent can never grant more than it has.
from agentpassport import sign_delegation, verify_auth_chain
# Root signs initial grant
token = sign_delegation(
issuer_private_key=root_priv,
issuer_did=root_did,
subject_did=agent.did,
scope=["read:db:customers"],
ttl_seconds=3600,
)
# Receiving agent verifies before acting
verify_auth_chain(
auth_chain=[token],
expected_subject=agent.did,
known_public_keys={root_did: root_pub},
)Capabilities declare what scope they need. agentpassport checks before the handler runs — fail fast, no partial state.
@agent.capability("query_customers", requires=["read:db:customers"])
async def handle(task: TaskEnvelope) -> dict:
# Only reached if auth chain grants read:db:customers
return {"customers": [...]}Revoke a delegation by JTI without stopping in-flight work — the agent completes its current action and stops before the next.
from agentpassport import InMemoryRevocationRegistry, SqliteRevocationRegistry
registry = SqliteRevocationRegistry("revocations.db")
registry.revoke(jti) # all future requests with this token failWire-compatible with Python — cross-language trust chains work out of the box.
import { Agent, InMemoryRevocationRegistry, ScopeError } from "@agentpassport/core"
const agent = new Agent("ts-agent", { privateKey, revocationRegistry })
agent.trustKeys({ [orchestratorDid]: orchestratorPublicKey })
agent.capability("queryCustomers", { requires: ["read:db:customers"] }, async (task) => {
return { customers: [...] }
})A Python orchestrator can sign a delegation JWT. A TypeScript agent can verify it. No shared infrastructure needed.
Scopes are action:resource pairs:
["read:db:customers", "write:api:stripe", "send:email:notifications"]
Both parts together make authorization provable. Action-only ("read") is too loose. Resource-only ("db:customers") is incomplete.
pip install agentpassport # Python SDK
pip install agentpassport[otel] # + OpenTelemetry sinkcd packages/agentpassport-ts && npm install # TypeScript SDK| Package | Description |
|---|---|
agentpassport |
Python trust and authorization layer |
@agentpassport/core |
TypeScript SDK (wire-compatible) |
agentpassport-registry |
Trusted agent registry with signature verification |
agentpassport-adapters |
MCP, REST, and A2A adapters |
agentpassport-cli |
CLI — keygen, trace viewer |
# Generate a keypair and DID
agentpass identity keygen --alias myagent
# Inspect an auth chain from a trace
agentpass trace show --id trace_abc --file traces.jsonlAgents can prove real-world ownership by publishing a signed binding document at /.well-known/agent-passport.json.
from agentpassport import (
generate_keypair, did_from_public_key,
bind_domain, bind_wallet, BindingDocument,
verify_binding_attestation,
)
priv, pub = generate_keypair()
did = did_from_public_key(pub)
# Create bindings
domain_binding = bind_domain(priv[:32], did, "agentpassport.fyi")
wallet_binding = bind_wallet(priv[:32], did, "ethereum", "0xYourAddress")
# Assemble and publish
doc = BindingDocument(version="1")
doc.add(domain_binding)
doc.add(wallet_binding)
print(doc.to_json()) # publish at https://agentpassport.fyi/.well-known/agent-passport.json
# Verify offline
ok = verify_binding_attestation(domain_binding) # TrueOr use the CLI:
agentpass identity bind-domain --alias myagent --domain agentpassport.fyi --output ap.json
agentpass identity bind-wallet --alias myagent --chain ethereum --address 0x... --output ap.json
agentpass identity verify-domain --did <DID> --domain agentpassport.fyiSee the Ownership Binding guide for the full flow.
| Feature | Status | |
|---|---|---|
| Authorization layer | Cryptographic agent identity (did:key:) |
✅ Done |
| Signed delegation chain (JWT) | ✅ Done | |
| Scope enforcement + revocation | ✅ Done | |
| Python SDK | ✅ Done | |
| TypeScript SDK | ✅ Done | |
| Cross-language wire compatibility | ✅ Done | |
| MCP middleware adapter | ✅ Done | |
| A2A protocol adapter (inbound + outbound) | ✅ Done | |
| AI Passport | Identity revocation | ✅ Done |
| Domain ownership binding | ✅ Done | |
| Wallet ownership binding (chain-agnostic) | ✅ Done | |
| Decentralized agent discovery | 🔜 Planned | |
| Merkle tree revocation (scalable, on-chain ready) | 🔜 Planned | |
| Human-readable ownership declaration | 🔜 Planned |
uv sync --all-packages
uv run pytest # Python tests (173)
cd packages/agentpassport-ts && npm test # TypeScript tests (48)
uv run python -m tests.cross-sdk.generate_fixtures && \
cd tests/cross-sdk && npx tsx generate_ts_fixtures.ts # cross-SDK fixturesPRs welcome. See CONTRIBUTING.md for guidelines.
Apache-2.0
