← AIP

Quickstart: Agent Identity in 5 Minutes

Install AIP, generate a keypair, create a signed token, and verify it. By the end you will have a working agent identity that produces MCP-compatible auth headers.

Prerequisites: Python 3.10+

1

Install

Pick your framework, or install the core SDK directly:

pip install aip-agents[crewai]

Or: aip-agents[adk], aip-agents[langchain], aip-agents[all], or just agent-identity-protocol for the core.

2

Generate a keypair

Every agent identity starts with an Ed25519 keypair:

from aip_core.crypto import KeyPair

kp = KeyPair.generate()
print(f"Public key: {kp.public_key_multibase()}")
print(f"AIP ID:     aip:key:ed25519:{kp.public_key_multibase()}")
Public key: z6Mkf5rGM...
AIP ID:     aip:key:ed25519:z6Mkf5rGM...

This is a self-certifying identity. No DNS, no certificate authority. The public key is the identity. For production, you can use DNS-based identities (aip:web:yourcompany.com/agent) with identity documents.

3

Create a signed token

A compact token (JWT + EdDSA) carries the agent's identity, scope, and budget:

from aip_token.claims import AipClaims
from aip_token.compact import CompactToken
import time

claims = AipClaims(
    iss="aip:key:ed25519:" + kp.public_key_multibase(),
    sub="aip:web:example.com/tools/search",
    scope=["tool:search"],
    budget_usd=1.0,
    max_depth=0,
    iat=int(time.time()),
    exp=int(time.time()) + 3600,  # 1 hour
)
token = CompactToken.create(claims, kp)
print(f"Token: {token[:60]}...")
Token: eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJpc3MiOi...

This token says: "I am aip:key:ed25519:z6Mkf5..., I want to call tool:search on example.com/tools/search, my budget is $1.00, and this token expires in one hour."

4

Verify it

The MCP server (or any verifier) checks the signature, expiry, and scope:

verified = CompactToken.verify(token, kp.public_key_bytes())
print(f"Issuer: {verified.iss}")
print(f"Scope:  {verified.scope}")
print(f"Budget: ${verified.budget_usd}")
Issuer: aip:key:ed25519:z6Mkf5rGM...
Scope:  ['tool:search']
Budget: $1.0
5

Send it to an MCP server

AIP tokens travel as X-AIP-Token headers:

import httpx

headers = {"X-AIP-Token": token}
response = httpx.post(
    "http://localhost:3000/mcp/tools/search",
    headers=headers,
    json={"query": "latest research on agent identity"}
)

The MCP server extracts the token from the header, verifies the signature against a trusted public key, checks that tool:search is in the token's scope, and either serves the request or returns 401.

Try to break it

Understanding what AIP rejects is as important as what it accepts.

Wrong scope:

# Token is scoped to ["tool:search"], but we try "tool:email"
wrong_claims = AipClaims(
    iss="aip:key:ed25519:" + kp.public_key_multibase(),
    sub="aip:web:example.com/tools/email",
    scope=["tool:email"],  # not authorized
    budget_usd=1.0,
    max_depth=0,
    iat=int(time.time()),
    exp=int(time.time()) + 3600,
)
# Server rejects: scope mismatch

Expired token:

# Token expired 10 seconds ago
expired_claims = AipClaims(
    iss="aip:key:ed25519:" + kp.public_key_multibase(),
    sub="aip:web:example.com/tools/search",
    scope=["tool:search"],
    budget_usd=1.0,
    max_depth=0,
    iat=int(time.time()) - 3610,
    exp=int(time.time()) - 10,  # already expired
)
expired_token = CompactToken.create(expired_claims, kp)
# CompactToken.verify raises: token expired

Tampered token:

# Flip a character in the token
tampered = token[:-5] + "XXXXX"
# CompactToken.verify raises: signature verification failed

Next steps