Universal Identity
for AI Agents
Open protocol for AI agent identity. Register a DID, sign requests with Ed25519, verify across platforms — anchored on Base L2.
# Python
pip install open-agent-id
# JavaScript / TypeScript
npm install @openagentid/sdk
# Rust
cargo add open-agent-idProtocol Flow
How the protocol works
From local key generation to on-chain anchoring and agent-to-agent trust — visualized step by step.
How Registration Works
The owner first authenticates with their Ethereum wallet to get a verified identity. Then the agent generates an Ed25519 keypair locally (via SSH or SDK) and registers the public key. Every agent is traceable to a real, verified wallet owner.
Think of it like opening a bank account: you show your ID first (wallet signature), then deposit your unique stamp pattern (public key). No anonymous accounts — every agent has a verified owner who can be held accountable.
How wallet authentication works (and why it can't be faked)
Every agent owner must prove their identity with an Ethereum wallet. Here's exactly what happens under the hood — no trust required, just math.
The registry generates a random, one-time string (e.g., "Sign this to authenticate: a8f3e2...") and sends it to the owner's browser.
Like a bank teller saying: "Please write this specific sentence on a piece of paper and sign it." The sentence is random and different every time, so no one can prepare a forgery in advance.
The owner's wallet (e.g., MetaMask) pops up asking them to sign the challenge string. The wallet uses the owner's Ethereum private key to produce a cryptographic signature — the private key never leaves the device.
MetaMask shows a popup: "This site wants you to sign a message." You click "Sign" — that's it. Your private key never leaves your device, never goes to the internet. It's like signing a document in a sealed room: only the signed document comes out, the pen stays inside.
The registry receives the signature and uses Ethereum's ecrecover function to mathematically derive the signer's wallet address from the signature alone — no secret needed. If the derived address matches the claimed address, the owner is verified.
Here's the clever part: the registry doesn't need your private key to verify you. Using math (ecrecover), it can look at your signature and figure out exactly which wallet address produced it. It's like a forensic handwriting expert who can identify the writer just from the signature — impossible to fake, no secrets exchanged.
Nothing secret is ever sent over the network. Your private key stays on your device at all times.
Each challenge is random and one-time. Even if someone intercepts a signature, they can't reuse it for a different challenge.
In practice, MetaMask pops up, you click "Sign", and you're verified. Same flow used by OpenSea, Uniswap, and thousands of dApps.
Agent-to-Agent Authentication
Agents sign requests with their private key and include identity headers. The receiving agent looks up the sender's public key from the registry and verifies the signature locally in under 0.1ms.
When Agent A sends a message to Agent B (or calls an MCP server tool), it stamps the message with its private key. The receiver checks the stamp against the registry. If it matches, the message is genuine. No shared passwords needed — nothing secret ever travels over the network. Each request includes a timestamp and a unique nonce (one-time random number) to prevent replay attacks: even if someone intercepts a message, they can’t reuse it.
System Architecture
The registry supports wallet auth (EIP-191). Agents register with BYOK (bring your own key), and identity hashes are anchored on Base L2 asynchronously via CREATE2. All lookups are cached in Redis.
The system has two layers: a fast centralized registry for everyday lookups (< 1ms), and a blockchain anchor for permanent, tamper-proof proof that an identity was registered. You get the speed of a database with the trust guarantees of a blockchain.
Why Open Agent ID
The missing identity layer for the agent economy
As AI agents proliferate, they need a universal way to prove who they are. Open Agent ID provides the cryptographic foundation.
Unique Identity
Every AI agent gets a globally unique DID — like a passport number that works across every platform.
Cryptographic Proof
Each agent holds a private key that only it knows. To verify identity, others check the matching public key from the registry — no shared passwords, no secrets over the network. Even if someone intercepts a message, they can't forge or reuse it.
Sub-Millisecond Verification
Verification is pure math — no network round-trip needed. Once a public key is cached, checking a signature takes less than 0.1ms locally.
Cross-Platform
One identity works everywhere. Agents can prove who they are to any service, any framework.
On-Chain Anchored
Identity proofs are anchored on Base L2 for immutability. Registration costs less than $0.01.
Open Standard
Apache-2.0 licensed. W3C DID compatible. No vendor lock-in. Build on an open foundation.
How It Works
Four steps to verified agent identity
From registration to on-chain proof in minutes. Works with Python, JavaScript, and Rust.
Register
Authenticate with your Ethereum wallet, generate an Ed25519 keypair (browser or SDK), and register the public key. The registry computes a deterministic CREATE2 address and issues your DID instantly — no on-chain transaction needed.
Like opening a bank account: you show your ID (wallet signature), then deposit your stamp pattern (public key). Your account number (DID) is ready immediately.
from agent_id import RegistryClient
client = RegistryClient("https://api.openagentid.org")
# Step 1: Wallet auth (proves you own this address)
challenge = await client.request_challenge("0xYourWallet")
# MetaMask pops up → you click "Sign"
token = await client.verify_wallet(
"0xYourWallet", challenge.id, signature
)
# Step 2: Register with BYOK public key
result = await client.register_agent(token, {
"name": "my-agent",
"capabilities": ["search"],
"public_key": public_key_b64url,
})
print(result["did"])
# did:oaid:base:0x1a2b3c...ef01Sign
When making API calls, your agent signs the request using the oaid-http/v1 domain. The signature covers method, URL, body hash, timestamp, and nonce — preventing replay and tampering.
Every message gets stamped, timestamped, and numbered — so no one can forge, reuse, or tamper with it.
from agent_id import sign_http_request
headers = sign_http_request(
private_key,
"POST",
"https://api.example.com/v1/tasks",
b'{"task": "translate"}',
)
# X-Agent-DID, X-Agent-Timestamp,
# X-Agent-Nonce, X-Agent-SignatureVerify
The receiving party looks up the agent's public key from the registry by DID and verifies the Ed25519 signature locally in under 0.1ms.
The receiver checks the stamp against the public directory — match means it's genuine, no secrets exchanged.
from agent_id import verify_http_signature
valid = verify_http_signature(
public_key,
method="POST",
url="https://api.example.com/v1/tasks",
body=request_body,
timestamp=ts,
nonce=nonce,
signature=sig_bytes,
)
# True — identity confirmedAnchor
Identity hashes are automatically anchored on Base L2 for tamper-proof, permanent proof of registration. The DID works immediately — anchoring happens asynchronously.
A fingerprint of the registration is permanently recorded on a public blockchain — proof that can never be altered or deleted.
info = await client.get_agent(did)
# {
# "did": "did:oaid:base:0x1a2b...",
# "chain_status": "anchored",
# "agent_address": "0x1a2b3c...",
# "public_key": "reIEYC6Gnz..."
# }Architecture
Two-layer trust model
Fast centralized reads with decentralized on-chain anchoring. The best of both worlds.
Owner authenticates via wallet (EIP-191) to prove identity. Agent generates keys locally and sends only the public key. DID + public key + verified owner stored in PostgreSQL, then asynchronously anchored on Base L2.
Public key lookups hit Redis cache first (1h TTL), then PostgreSQL. Sub-millisecond verification with no chain interaction needed.
Only keccak256 hashes stored on-chain (~96 bytes per agent). Full data lives off-chain. Registration costs < $0.01 on Base L2.
Base is an Ethereum Layer 2 network built by Coinbase using the OP Stack. Think of Ethereum mainnet (L1) as a congested highway — Base (L2) is a fast lane built alongside it that periodically settles back to L1 for security. We chose Base because: on-chain writes cost < $0.01 (vs $5-50 on L1), blocks confirm in ~2 seconds, security is inherited from Ethereum, and the Coinbase ecosystem ensures long-term reliability. Day-to-day verification never touches the chain — it happens locally in < 0.1ms. The chain is only used as a permanent, tamper-proof receipt of registration.
Protocol
DID format specification
Each agent gets a globally unique Decentralized Identifier derived from a CREATE2 address — available instantly, anchored on-chain asynchronously.
oaid-http/v1\n{METHOD}\n{CANONICAL_URL}\n{SHA256(body)}\n{timestamp}\n{nonce}X-Agent-DID, X-Agent-Timestamp, X-Agent-Nonce, X-Agent-Signatureoaid-msg/v1\n{type}\n{id}\n{from_did}\n{sorted_to}\n{ref}\n{ts}\n{expires}\n{SHA256(body)}Use Cases
Built for the agent economy
From API authentication today to cross-platform reputation tomorrow.
API Call Authentication
Agent signs every API request. The receiving service verifies the caller's identity in < 0.1ms — no shared secrets, no API key leaks.
Cross-Agent Communication
Two agents exchange signed messages and verify each other's identity through the public registry. Trust without prior introductions.
MCP Server Authentication
Agents sign every tool call to MCP servers with their DID. The server verifies who's calling, controls which tools each agent can access, and logs an auditable trail — no shared API keys needed.
Usage Attribution & Billing
Every request is cryptographically signed. Attribute usage to specific agents for accurate billing and audit trails.
Sybil & Spoofing Prevention
On-chain identity anchoring makes it costly to create fake agent identities. Detect and block impersonation attacks.
Cross-Platform Reputation
An agent's identity and track record follow it across platforms. Build trust scores that are portable and verifiable.
Regulatory Compliance
Immutable on-chain records provide the audit trail regulators need. Prove which agent did what, when, with cryptographic certainty.
SDKs
First-class SDK support
Production-ready libraries for Python, JavaScript/TypeScript, and Rust. Same protocol, two signing domains, any language.
from agent_id import RegistryClient, sign_http_request
from agent_id.crypto import generate_ed25519_keypair, base64url_encode
client = RegistryClient("https://api.openagentid.org")
# Step 1: Wallet auth
challenge = await client.request_challenge("0xYourWallet")
signature = wallet.sign(challenge["challenge_text"])
auth = await client.verify_wallet(
"0xYourWallet", challenge["challenge_id"], signature
)
# Step 2: Generate keys & register
private_key, public_key = generate_ed25519_keypair()
result = await client.register_agent(auth["token"], {
"name": "my-search-agent",
"capabilities": ["search", "summarize"],
"public_key": base64url_encode(public_key),
})
print(f"DID: {result['did']}")
# did:oaid:base:0x1a2b3c4d...ef01
# Sign HTTP requests (oaid-http/v1)
headers = sign_http_request(
private_key,
"POST",
"https://api.example.com/v1/search",
b'{"query": "AI agents"}',
)
# Verify another agent
valid = verify_http_signature(
their_public_key,
method, url, body,
timestamp, nonce, signature,
)Documentation
Everything you need to get started
Protocol Specification
DID format, signing scheme, and verification workflow.
Read the specAPI Reference (OpenAPI)
Full REST API documentation for the Registry server.
View API specSDK Documentation
Guides and API reference for Python, JS/TS, and Rust SDKs.
Browse SDKsSmart Contract
AgentRegistry.sol source code and deployment details.
View contractQuick Start (Python)
Registration requires two things: wallet authentication (to verify the owner) and key generation (for the agent).
Sign a challenge with your Ethereum wallet to prove you're a real owner. Your wallet address becomes the agent's verified owner_id — no anonymous bots, every agent traceable to a person.
Generate an Ed25519 keypair with ssh-keygen (familiar) or let the SDK handle it automatically (easiest). Either way, the private key never leaves your machine.
Recommended: SDK handles everything
# 1. Install
pip install open-agent-id
# 2. Wallet auth (proves you own this address)
from agent_id import AgentIdentity
challenge = await AgentIdentity.get_challenge("0xYourWallet")
signature = wallet.sign(challenge) # MetaMask popup
wallet_token = await AgentIdentity.wallet_auth(
"0xYourWallet", signature
)
# 3. Register — SDK generates keys automatically
identity = await AgentIdentity.register(
name="my-agent",
capabilities=["search"],
wallet_token=wallet_token,
)
print(identity.did) # did:agent:platform:agt_a1B2...
print(identity.owner_id) # 0xYourWallet (verified)Alternative: ssh-keygen + API
# 1. Generate keypair (familiar!)
ssh-keygen -t ed25519 -f agent_key -N ""
# 2. Register via API with wallet token + public key
curl -X POST https://api.openagentid.org/v1/agents \
-H "Authorization: Bearer $WALLET_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"my-agent","public_key":"<agent_key.pub>"}'