RFC 0001 - Draft Standard

The Trust Layer
for AI Agents

Agent Identity Protocol gives every AI agent a verifiable identity, cryptographically-scoped authority, and an unforgeable audit trail across MCP and A2A.

Scroll
The Problem

AI agents operate in a trust void

Today's agent ecosystem has no standard way to answer the most basic security question: who is this agent, and what is it allowed to do?

2,000+MCP servers scanned - zero with auth
0Standard agent identity formats
100%A2A delegations with no audit trail

The trust gap in numbers

A survey of the MCP ecosystem found over 2,000 publicly accessible servers, none of which implement authentication or identity verification. An attacker can impersonate any server or agent, and no existing mechanism can trace which agent invoked which tool on whose behalf. The Agent Identity Protocol closes this gap.

Core Concepts

Three ideas that fix agent trust

AIP introduces three simple but powerful primitives built on established cryptographic standards.

A Passport for Agents

Every agent gets a globally unique, cryptographically verifiable Decentralized Identifier (DID). Like a passport, it proves who the agent is to any service it talks to - no central registry required.

Delegation with Handcuffs

An agent can authorize another agent to act on its behalf, but with strict limits: a budget, an expiration, a specific toolset. Attenuation ensures delegated power cannot be misused - even by accident.

The Paper Trail

Every delegation and invocation is recorded in an append-only provenance chain. You can trace exactly who authorized what, producing a complete audit trail from the original request to every sub-task.

Interactive Diagrams

See the protocol in motion

Watch how tokens grow, compare wire formats, and follow the verification process step by step.

Token Growth

IBCT chain grows with each delegation

User
Agent A
Agent B
Task: search flights
Token size: 1 block

The token grows with each delegation. Each hop appends identity, capability, and provenance - append-only, unforgeable.

Wire Formats

Compact vs Chained side by side

Single JWT
Header
"alg": "ES256K"
Payload
"iss": "did:aip:alice"
"cap": {"read": ["reports/"]}
"exp": 1719000000
Signature
0x7a8b...3f1e

One flat token. Best for single-hop MCP calls where no delegation chain exists.

Multi-block
Block 0 (Issuer)
right("read", path) <- resource(path)
Block 1 (Delegate)
right("read", path) <- resource(path)
Block 2 (Completion)
right("read", path) <- resource(path)

Each hop appends a block. The token carries the full provenance tree.

Verification

The verification loop in action

Verification Engine
1. Receive Tokenrunning...
2. Verify Signature
3. Evaluate Datalog
4. Check Attenuation
5. Execute Tool
Technical Deep Dive

Built on three technical pillars

AIP combines identity, capability-based authorization, and provenance into a single, extensible protocol.

IBCT

Invocation-Bound Capability Tokens

IBCTs are the core cryptographic primitive of AIP. They fuse three concerns into one atomic token: identity (who issued it), authorization (what the bearer can do), and provenance (the chain of delegations that produced it). Each IBCT binds a capability directly to a specific invocation context, preventing token reuse across different operations.

  • Cryptographically signed by the issuer's DID
  • Encodes the exact scope of delegated authority
  • Chains parent-child relationships for full provenance
  • Single-use by default; replay-attack resistant
python
# Create an IBCT for a sub-agent
token = IBCT.create(
    issuer=agent_a.did,
    subject=agent_b.did,
    capabilities={
        "tool:search": {"max_results": 10},
        "tool:read": {"paths": ["docs/*"]},
    },
    constraints={
        "exp": int(time()) + 3600,
        "max_depth": 2,
    },
    parent=parent_token,
)
# token now carries: identity,
# attenuation, and provenance
Dual Wire

Two wire formats for every scenario

Compact Mode

Single-hop MCP calls

Signed JSON Web Tokens (JWTs) for direct, single-hop invocations. The entire IBCT - identity, capability, and parent reference - is encoded as standard JWT claims.

jwt
{
  "iss": "did:aip:alice-agent",
  "cap": {"read": ["reports/"]},
  "exp": 1719000000
}
[SIGNED WITH ES256K]
Chained Mode

Multi-hop delegation

Biscuit tokens with embedded Datalog policies for multi-hop delegation chains. Each hop appends a new block with attenuated capabilities.

datalog
// Block 0
right("read", path) <-
  resource(path), prefix(path, "reports/");
// Block 1
right("read", path) <-
  right("read", path),
  check(limit(path, 5MB));
Datalog

Logic-based policy engine

In chained mode, AIP uses Datalog - a declarative logic programming language - to express and verify access policies. Each delegation block adds rules or checks that the token must satisfy.

  • Budget caps: limit total API spend per delegation chain
  • Time bounds: tokens expire or activate on schedule
  • Depth limits: max 3 hops before re-authorization required
  • Scope narrowing: each hop can only restrict, never expand
datalog
// Policy: budget check
allow if
  budget_remaining(B),
  B >= cost(C),
  cost(C);

// Policy: time window
allow if
  time(T),
  T >= 2025-03-20T00:00:00Z,
  T <= 2025-03-21T00:00:00Z;

// Attenuation rule
right(tool, path) <-
  parent_right(tool, path),
  allowed_scope(tool, path);
Practical Examples

Real-world flows with concrete code

See how AIP protects a database tool, enables multi-agent travel booking, and how to build tokens from scratch.

MCP Tool Protection

Protecting a sensitive database tool

The read_database tool is one of the most sensitive endpoints in any MCP server. With AIP, you add a middleware layer that verifies every invocation against a Datalog policy before the tool handler is ever reached.

  • Token must authorize access to the specific database
  • Operation restricted to SELECT only - no mutations
  • Time-bound: access expires after a cutoff date
  • Full provenance recorded for audit compliance
Datalog Policy
allow if resource == "db_1", operation == "select", time < 2026-07-01T00:00:00Z;
python
from aip import AIPMiddleware, IBCTVerifier

server = MCPServer()

@server.tool("read_database")
def read_db(query: str):
    # Only reached if AIP verified:
    # 1. Token signed by authorized issuer
    # 2. Datalog policy: resource="db_1", 
    #    operation="select", time < cutoff
    # 3. Attenuation constraints met
    return db.execute(query)

# Wrap with AIP middleware
server.use(AIPMiddleware(
    verifier=IBCTVerifier(),
    resolver=DIDResolver(),
    policy_file="policies/db.datalog",
))
A2A Delegation

Travel Coordinator delegates hotel booking

You
Travel Coord
Hotel Booker
Hotel API
Step 1: User request

"Book a hotel in Paris under $200/night, June 15-20."

python
# User invokes Travel Coordinator
result = travel_agent.invoke(
    task="book_hotel",
    params={
        "city": "Paris",
        "max_price": 200,
        "check_in": "2026-06-15",
        "check_out": "2026-06-20",
    },
)
Step 2: Delegation with constraints

Travel Coordinator delegates to Hotel Booker with an attenuated IBCT.

python
# Travel Coordinator delegates
delegation = agent.delegate(
    target=hotel_booker.did,
    task="search_and_book",
    constraints={
        "max_price": 200,
        "city": "Paris",
        "dates": ["2026-06-15", "2026-06-20"],
        "max_depth": 1,
    },
)

# Hotel Booker calls hotel API
result = hotel_booker.call_tool(
    server=hotel_api_mcp,
    tool="search",
    params={"city": "Paris"},
    ibct=delegation.token,
)
Step 3: Verified result

Hotel API verifies the token, returns results. Provenance recorded.

python
# Token verified, provenance
# chain recorded:
# User -> Travel Coordinator
# -> Hotel Booker -> Hotel API

print(result)
# Hotel: Le Marais Inn
# Price: $185/night
# Dates: June 15-20
# Provenance:
#   3 hops, all verified
Sample Code

Building tokens with BiscuitBuilder

python
from aip import BiscuitBuilder, check

# Initialize the builder
builder = BiscuitBuilder("ed25519")

# Add a Datalog check
builder.add_check(
    check(
        'resource == "db_1"',
        'operation == "select"',
        'time < 2026-07-01T00:00:00Z',
    )
)

# Add attenuation rules
builder.add_right(
    'right(op, res) <- '
    'parent_right(op, res), '
    'allowed_scope(op, res)'
)

# Sign and export the token
token = builder.sign(
    secret_key=issuer_key,
    expiry=3600,
)
print(f"Token: {token.to_base64()}")
# Token now carries:
# identity, policy, signature
rust
use aip::biscuit::BiscuitBuilder;

let mut builder = BiscuitBuilder::new();

// Add a Datalog check
builder.add_check(
    check!(r#"resource == "db_1""#,
           r#"operation == "select""#,
           r#"time < 2026-07-01T00:00:00Z"#)
);

// Attenuation rule
builder.add_right(
    r#"right(op, res) <-
        parent_right(op, res),
        allowed_scope(op, res)"#,
);

// Sign
let token = builder
    .sign(&issuer_key)
    .with_expiry(3600)
    .build()
    .await?;

println!("Token: {}", token.to_base64());
// Verify on receiving side
let data = token.verify(&issuer_pub).await?;
assert!(data.operations.contains("select"));
Integration Guide

Add AIP to your existing services

AIP sits as a middleware layer. Drop it into any MCP server or A2A agent runtime without changing your business logic.

MCP Binding

Secure your MCP server

Add the AIP middleware to your existing MCP server. Every incoming tool call is verified against the caller's IBCT before reaching your handler. No code changes to your tool implementations.

python
from aip import AIPMiddleware

# Wrap your MCP server
server = MCPServer(tools=[search, read, write])
server.use(AIPMiddleware(
    verifier=IBCTVerifier(),
    resolver=DIDResolver(),
))

# Every call is now verified:
# 1. Extract IBCT from request header
# 2. Verify signature against issuer DID
# 3. Evaluate Datalog policy chain
# 4. Check attenuation constraints
# 5. Record provenance entry
# 6. Route to tool handler
A2A Delegation

Cross-agent delegation

Agent A receives a task, identifies it needs help, and delegates a sub-task to Agent B. Agent B gets an attenuated IBCT that limits what it can do, for how long, and on what data. The delegation chain is provable end-to-end.

python
# Agent A delegates to Agent B
delegation = agent_a.delegate(
    target=agent_b.did,
    task="summarize:reports/Q4.md",
    constraints={
        "max_tokens": 2000,
        "expires_in": 300,
    },
)

# Agent B invokes with its token
result = agent_b.call_tool(
    server=reports_mcp,
    tool="summarize",
    params={"path": "Q4.md"},
    ibct=delegation.token,
)  # Verified end-to-end
Get Involved

Help build the trust layer

AIP is an open protocol. Read the paper, explore the reference implementation, and join the working group.