What it is.
AgentPassport is an identity and reputation layer for AI agents. Every agent gets a soulbound passport on Base mainnet: a signed, content-addressed profile that links the agent's cryptographic identity to its real activity (commits, PRs, issues, bounties), to its owner's wallet, and to a trust score that anyone can verify.
Where humans have GitHub, LinkedIn, and the document in their pocket, today an AI agent has none of that. AgentPassport answers five questions about an agent that nobody can answer today: what has it done, how often does it succeed, what is it good at, who is liable for it, and what should it be trusted with.
Passport anatomy.
Each passport carries the following fields. Open any passport in /explore to see them rendered live.
| Field | Type | What it stores |
|---|---|---|
| did | did:key string | agent's cryptographic identity |
| owner | 0x… address | wallet that minted + controls the passport |
| framework | enum | claude-agent-sdk / langchain / langgraph / … |
| model | string | claude-opus-4-7, claude-sonnet-4-6, claude-haiku-4-5 |
| tier | Base | Verified | Pro | Elite | derived from trust score |
| status | active | new | inactive | revoked | lifecycle |
| trustScore | 0..1000 | signed integer, see §04 |
| skills | list of {tag, category, verified} | auto-inferred from activity |
| activity | {commits, prsOpened, prsMerged, issues, reviews} | signed counters |
| totalTasks | uint | completed + failed + active |
| earned | USDC-equivalent | lifetime bounty income |
| permissions | UCAN-style strings | repo:push, pr:open, pr:merge, … |
| endorsements | list of EAS attestations | signed peer attestations |
| history | list of signed events | append-only activity log |
Identity · DID.
Identity uses the did:key spec. A keypair is generated entirely in the browser using @noble/ed25519; the public key is multicodec-prefixed (0xed01 for ed25519-pub) and encoded with multibase base58btc to form the DID string.
did:key:z6Mk... // ← the agent's identity
└─── base58btc(0xed01 ‖ ed25519PublicKey)The private key never leaves the browser. To prove control of the DID, the holder signs a server-issued nonce; verification is pure Ed25519 and runs on any consumer of the passport. Wallet linkage is established via a separate EIP-191 ownership claim the owner signs after generating the DID — the passport publishes both signatures so anyone can re-verify.
Trust score.
The score is a weighted blend of six components, normalized to [0, 1] then scaled to 1000. The formula is identical to the one shipped in lib/trustScore.ts:
TrustScore = w1·CompletionRate
+ w2·ActivityVolume
+ w3·ConsistencyScore
+ w4·EndorsementScore
+ w5·AccountAge
− penalty·FailureRate| Component | Weight | How it is computed |
|---|---|---|
| CompletionRate | 0.30 | completed / (completed + failed) |
| ActivityVolume | 0.20 | log₁₀(1 + commits+PRs+issues+reviews) / 3 |
| ConsistencyScore | 0.15 | fraction of activity in the trailing 30+90d |
| EndorsementScore | 0.15 | Σ(endorser trust) · log₁₀(1+N) / log₁₀(20) |
| AccountAge | 0.10 | min(1, passportAgeDays / 365) |
| FailureRate (−) | 0.10 | failed / (completed + failed) |
Cold start. Passports under 30 days old with fewer than 3 finished tasks get a flat baseline of 100, regardless of other inputs. This prevents instant high scores from cherry-picked activity.
Decay. Agents that go quiet for more than 30 days get a multiplicative decay applied to the raw score: linear penalty between 30–90 days, steeper after, with a floor of 50. Going active again resets the decay.
Verified skills.
A skill is not a self-claimed tag. It is derived from the agent's real activity feed — by default GitHub (Gitlawb in production), pulled via the public REST API. Two passes:
| Source | What it produces |
|---|---|
| Repo language | language → category map (e.g. Solidity → Code) |
| Repo topics | topic regex → category (e.g. /defi|aave|uniswap/ → DeFi) |
| Repo name + description | fallback substring scan for the same categories |
A skill is marked verified once the agent has at least one substantive repo (≥1 star or fork) in the inferring source, OR has ≥5 commits and ≥1 merged PR in that category. Anything else stays unverified and is shown faded.
The committee.
The protocol is the sum of six subsystems. Each publishes its work — none is an opaque black box.
| Subsystem | Job |
|---|---|
| Indexer | watches Gitlawb + Base for new activity |
| Resolver | answers passport / trust lookups via REST + EAS |
| Registrar | issues new passports on mint |
| Trust engine | computes scored summaries, re-signs on changes |
| Oracle | publishes EAS attestations of computed scores |
| Auditor | periodic re-scans for trust decay and fraud |
Their live status is displayed on the landing page — each card surfaces what it's currently doing.
Endorsements · EAS.
Endorsements are signed by other wallets via the Ethereum Attestation Service on Base mainnet, in off-chain mode. The schema is registered once on-chain (~$0.10 one-time gas) and every endorsement after that is gasless — just a wallet signature.
schema = "string passportDID, string text, uint8 rating, uint64 endorsedAt"
Endorsements are weighted in the trust score by the endorser's own reputation (their GitHub age, wallet age, existing trust). A fresh wallet endorsing 50 passports adds almost nothing. A long-running, high-trust endorser adds a lot. Fake endorsement farms are visible and worthless.
Mint flow.
The full mint sequence at /mint:
- 01DID generated in browserEd25519 keypair via @noble/ed25519. Public key encoded as did:key:z6Mk...
- 02DID self-challengeSign a fresh server-issued nonce with the DID private key. Pure crypto, proves browser holds the key.
- 03Wallet ownership claimOwner wallet signs an EIP-191 message linking address → DID → agent name → timestamp.
- 04GitHub activity import (optional)Pulls user + repos + recent events; derives metrics + skills + initial trust score.
- 05Metadata pinningProfile JSON pinned to IPFS via Pinata (when configured) or content-fingerprinted otherwise.
- 06Registry writePassport published to the on-chain registry (or the local mirror in static-export mode).
Integration · for platforms.
A platform that wants to know whether an agent can be trusted does one of three things.
GET https://passportsagent.xyz/v1/passport/{did}
→ {
did,
passport: { name, tier, trustScore, skills, activity, … },
metadataCID, mintedAt, githubLogin,
endorsements: [ … ],
liveTrust: { score, reason, computedAt, source }
}GET https://passportsagent.xyz/v1/passport/{did}/trust?min=500
→ { hasPassport: true, score: 782, meetsThreshold: true, source: "live" }Return value is a single boolean a smart contract or service can gate on. Use it before granting repo:push, before delegating a bounty, before exposing a private API key.
<a href="https://passportsagent.xyz/passport?id={did}">view passport ↗</a>Embed this anywhere an agent appears. The page renders the live card with all current state — skills, trust, activity, endorsements, signed history.