IATP
Inter-Agent Trust Protocol — Cryptographic Identity for Multi-Agent Systems
What is IATP?
The Inter-Agent Trust Protocol (IATP) provides cryptographic identity and message signing for multi-agent AI systems. In environments where multiple agents collaborate, compete, or delegate tasks, trust is paramount.
IATP solves critical security challenges:
- Agent Impersonation: Prevent malicious agents from pretending to be trusted ones
- Message Integrity: Ensure messages haven't been tampered with in transit
- Trust Chains: Establish verifiable hierarchies of trust between agents
- Capability Attestation: Cryptographically prove what an agent is authorized to do
- Non-repudiation: Agents cannot deny actions they've signed
from agent_os.iatp import AgentIdentity, TrustRegistry
# Create a cryptographic identity for an agent
agent = AgentIdentity.create("finance-agent")
# Sign a message proving authenticity
signed_msg = agent.sign({
"action": "approve_transaction",
"amount": 50000,
"recipient": "vendor-123"
})
# Any agent can verify the signature
is_valid = AgentIdentity.verify(signed_msg)
# is_valid: True
Installation
Install IATP as a standalone module or as part of the full kernel:
# Standalone installation
pip install agent-os-iatp
# With full kernel
pip install agent-os-kernel[iatp]
# With hardware security module support
pip install agent-os-iatp[hsm]
# With distributed registry support
pip install agent-os-iatp[distributed]
Requirements
- Python 3.9+
- cryptography >= 41.0.0
- pynacl >= 1.5.0 (for Ed25519 signatures)
AgentIdentity Class
The AgentIdentity class is the core primitive for cryptographic identity.
Each identity consists of a keypair (private + public key) and associated metadata.
Creating an Identity
from agent_os.iatp import AgentIdentity
# Create a new identity with auto-generated keys
agent = AgentIdentity.create(
agent_id="research-agent",
metadata={
"role": "researcher",
"department": "R&D",
"created_by": "system-admin"
}
)
# Access identity properties
print(agent.agent_id) # "research-agent"
print(agent.public_key) # Base64-encoded public key
print(agent.fingerprint) # SHA256 fingerprint for easy identification
Exporting an Identity
Export identities for storage or transfer. Private keys can be encrypted with a passphrase.
# Export public key only (safe to share)
public_export = agent.export_public()
# {
# "agent_id": "research-agent",
# "public_key": "base64...",
# "fingerprint": "sha256:abc123...",
# "metadata": {...}
# }
# Export full identity (includes private key - KEEP SECURE!)
full_export = agent.export(
passphrase="secure-passphrase-here",
format="pem" # or "jwk", "raw"
)
# Save to file
agent.save("./identities/research-agent.pem", passphrase="secret")
Importing an Identity
# Import from exported data
agent = AgentIdentity.from_export(
export_data,
passphrase="secure-passphrase-here"
)
# Load from file
agent = AgentIdentity.load(
"./identities/research-agent.pem",
passphrase="secret"
)
# Import public key only (for verification)
public_agent = AgentIdentity.from_public_key(
agent_id="research-agent",
public_key="base64-encoded-public-key..."
)
Key Algorithms
IATP supports multiple cryptographic algorithms:
| Algorithm | Use Case | Key Size |
|---|---|---|
ed25519 |
Default, fast signatures | 256 bits |
rsa-4096 |
Legacy compatibility | 4096 bits |
ecdsa-p384 |
NIST compliance | 384 bits |
# Create identity with specific algorithm
agent = AgentIdentity.create(
agent_id="compliance-agent",
algorithm="ecdsa-p384" # NIST-approved
)
SignedMessage Class
The SignedMessage class represents a cryptographically signed payload.
It bundles the original message, signature, and signer information.
Signing Messages
from agent_os.iatp import AgentIdentity, SignedMessage
agent = AgentIdentity.create("trading-agent")
# Sign any serializable data
signed = agent.sign({
"action": "execute_trade",
"symbol": "AAPL",
"quantity": 100,
"price": 150.00,
"timestamp": "2024-01-15T10:30:00Z"
})
# SignedMessage properties
print(signed.payload) # Original message
print(signed.signature) # Base64 signature
print(signed.signer_id) # "trading-agent"
print(signed.public_key) # Signer's public key
print(signed.timestamp) # When it was signed
print(signed.algorithm) # "ed25519"
Verifying Signatures
# Method 1: Verify with embedded public key
is_valid = SignedMessage.verify(signed)
# Method 2: Verify against known identity
is_valid = agent.verify_signature(signed)
# Method 3: Verify against TrustRegistry
registry = TrustRegistry()
is_valid, trust_level = registry.verify(signed)
# Comprehensive verification with details
result = SignedMessage.verify_detailed(signed)
# {
# "valid": True,
# "signer_id": "trading-agent",
# "fingerprint": "sha256:abc123...",
# "signed_at": "2024-01-15T10:30:00Z",
# "algorithm": "ed25519",
# "payload_hash": "sha256:def456..."
# }
Message Chaining
Create chains of signed messages for audit trails:
# Agent A initiates a request
agent_a = AgentIdentity.create("requester")
request = agent_a.sign({
"type": "approval_request",
"amount": 10000
})
# Agent B approves (chains to original)
agent_b = AgentIdentity.create("approver")
approval = agent_b.sign({
"type": "approval",
"original_request": request.to_dict(),
"decision": "approved"
})
# Verify the entire chain
chain_valid = SignedMessage.verify_chain([request, approval])
TrustRegistry
The TrustRegistry manages known agent identities and their trust levels.
It acts as a certificate authority for your multi-agent system.
Creating a Registry
from agent_os.iatp import TrustRegistry, TrustLevel
# In-memory registry (for development)
registry = TrustRegistry()
# Persistent registry (for production)
registry = TrustRegistry(
backend="sqlite",
path="./trust-registry.db"
)
# Distributed registry (for multi-node deployments)
registry = TrustRegistry(
backend="redis",
url="redis://localhost:6379",
namespace="prod-agents"
)
Registering Agents
# Register an agent with a trust level
agent = AgentIdentity.create("data-processor")
registry.register(
identity=agent,
trust_level=TrustLevel.MEDIUM,
capabilities=["read_data", "process_data"],
expires_at="2025-01-01T00:00:00Z", # Optional expiration
metadata={
"registered_by": "admin",
"department": "engineering"
}
)
# Bulk registration
registry.register_many([
(agent1, TrustLevel.HIGH, ["admin"]),
(agent2, TrustLevel.LOW, ["read_only"]),
(agent3, TrustLevel.MEDIUM, ["read", "write"]),
])
Verifying Against Registry
# Check if an agent is registered and trusted
is_trusted = registry.is_trusted(agent.fingerprint)
# Get detailed trust information
trust_info = registry.get_trust_info(agent.fingerprint)
# {
# "agent_id": "data-processor",
# "trust_level": TrustLevel.MEDIUM,
# "capabilities": ["read_data", "process_data"],
# "registered_at": "2024-01-10T...",
# "expires_at": "2025-01-01T...",
# "revoked": False
# }
# Verify a signed message with trust context
result = registry.verify_message(signed_message)
# {
# "signature_valid": True,
# "signer_trusted": True,
# "trust_level": TrustLevel.MEDIUM,
# "has_capability": True # If capability check requested
# }
Revoking Trust
# Revoke an agent's trust (e.g., compromised key)
registry.revoke(
fingerprint=agent.fingerprint,
reason="Key compromised",
revoked_by="security-admin"
)
# Check revocation status
is_revoked = registry.is_revoked(agent.fingerprint)
# Get revocation details
revocation = registry.get_revocation(agent.fingerprint)
# {
# "revoked_at": "2024-01-15T...",
# "reason": "Key compromised",
# "revoked_by": "security-admin"
# }
Trust Levels
IATP defines five trust levels that determine what actions an agent can perform:
| Level | Value | Description | Typical Use |
|---|---|---|---|
NONE |
0 | No trust, all actions blocked | Unknown/revoked agents |
LOW |
1 | Minimal trust, read-only access | New agents, external systems |
MEDIUM |
2 | Standard trust, normal operations | Verified internal agents |
HIGH |
3 | Elevated trust, sensitive operations | Core system agents |
ADMIN |
4 | Full trust, can modify trust registry | System administrators |
from agent_os.iatp import TrustLevel
# Compare trust levels
if agent_trust >= TrustLevel.MEDIUM:
allow_write_access()
# Trust level gates
@registry.require_trust(TrustLevel.HIGH)
async def sensitive_operation(signed_request):
# Only HIGH or ADMIN trust can execute this
pass
# Dynamic trust requirements
required_level = TrustLevel.from_action("delete_user") # Returns HIGH
if registry.get_trust_level(agent) >= required_level:
proceed_with_action()
Trust Level Policies
# Define trust policies
policy = TrustPolicy(
default_level=TrustLevel.LOW,
action_requirements={
"read_*": TrustLevel.LOW,
"write_*": TrustLevel.MEDIUM,
"delete_*": TrustLevel.HIGH,
"admin_*": TrustLevel.ADMIN
},
auto_elevate=False, # Require explicit elevation
require_mfa_above=TrustLevel.HIGH # MFA for HIGH+
)
registry = TrustRegistry(policy=policy)
Capability Attestation
Capabilities are cryptographically signed tokens that prove an agent is authorized to perform specific actions. They can be delegated, scoped, and time-limited.
Creating Capabilities
from agent_os.iatp import Capability, AgentIdentity
# Admin agent creates a capability
admin = AgentIdentity.load("admin.pem", passphrase="...")
capability = Capability.create(
issuer=admin,
subject="data-processor", # Who receives this capability
actions=["read_customer_data", "process_orders"],
resources=["customers/*", "orders/*"],
constraints={
"max_records": 1000,
"rate_limit": "100/minute"
},
valid_from="2024-01-01T00:00:00Z",
valid_until="2024-12-31T23:59:59Z",
delegatable=False # Cannot be passed to other agents
)
Using Capabilities
# Agent attaches capability to request
agent = AgentIdentity.create("data-processor")
request = agent.sign({
"action": "read_customer_data",
"customer_id": "cust-123"
})
# Attach the capability as proof of authorization
request.attach_capability(capability)
# Verifier checks both signature AND capability
result = registry.verify_authorized(request)
# {
# "signature_valid": True,
# "capability_valid": True,
# "action_authorized": True,
# "constraints_satisfied": True
# }
Capability Delegation
# Create a delegatable capability
admin_cap = Capability.create(
issuer=admin,
subject="team-lead",
actions=["read_*", "write_*"],
delegatable=True,
max_delegation_depth=2 # Can delegate up to 2 levels deep
)
# Team lead delegates subset to team member
team_lead = AgentIdentity.create("team-lead")
delegated_cap = admin_cap.delegate(
delegator=team_lead,
subject="team-member",
actions=["read_*"], # Can only delegate subset
valid_until="2024-06-30T23:59:59Z" # Cannot exceed parent
)
# Verify delegation chain
chain_valid = Capability.verify_delegation_chain(delegated_cap)
Revocation and Key Rotation
Security best practices require regular key rotation and the ability to quickly revoke compromised credentials.
Key Rotation
from agent_os.iatp import AgentIdentity, TrustRegistry
agent = AgentIdentity.load("agent.pem", passphrase="old-secret")
# Rotate to new key pair
new_agent = agent.rotate_keys(
new_passphrase="new-secret",
rotation_proof=True # Signs new key with old key
)
# Update in registry (maintains trust level and history)
registry.rotate_identity(
old_fingerprint=agent.fingerprint,
new_identity=new_agent,
reason="Scheduled rotation"
)
# Old key is automatically added to revocation list
# but messages signed before rotation remain valid
Automated Rotation Policies
from agent_os.iatp import RotationPolicy
policy = RotationPolicy(
max_key_age_days=90,
warn_before_days=14,
auto_rotate=True,
notify_on_rotation=["security@company.com"],
backup_old_keys=True,
backup_retention_days=365
)
registry = TrustRegistry(rotation_policy=policy)
# Check rotation status
status = registry.check_rotation_status()
# [
# {"agent_id": "agent-1", "days_until_rotation": 5, "status": "warning"},
# {"agent_id": "agent-2", "days_until_rotation": 45, "status": "ok"},
# ]
Emergency Revocation
# Immediate revocation (compromised key)
registry.revoke_immediately(
fingerprint=compromised_agent.fingerprint,
reason="Key compromised - security incident #1234",
revoked_by="security-team",
broadcast=True # Notify all connected registries
)
# Revoke all capabilities issued by this agent
registry.revoke_capabilities_by_issuer(compromised_agent.fingerprint)
# Revoke with grace period (planned decommission)
registry.revoke_scheduled(
fingerprint=old_agent.fingerprint,
effective_at="2024-02-01T00:00:00Z",
reason="Agent decommissioned"
)
Certificate Revocation Lists
# Get current CRL
crl = registry.get_revocation_list()
# Export CRL for offline verification
crl_data = registry.export_crl(format="json")
# Check against CRL
is_revoked = registry.check_crl(
fingerprint=agent.fingerprint,
crl=crl_data
)
# Subscribe to revocation updates
@registry.on_revocation
async def handle_revocation(event):
print(f"Agent {event.agent_id} was revoked: {event.reason}")
await invalidate_cached_sessions(event.fingerprint)
Distributed Trust Networks
For large-scale deployments, IATP supports distributed trust networks where multiple registries can share and synchronize trust information.
Federation Setup
from agent_os.iatp import TrustRegistry, TrustFederation
# Create local registry
local_registry = TrustRegistry(
node_id="us-east-1",
backend="postgres",
url="postgresql://..."
)
# Join a federation
federation = TrustFederation(
registries=[
"https://trust.us-east-1.example.com",
"https://trust.eu-west-1.example.com",
"https://trust.ap-south-1.example.com"
],
consensus="majority", # 2 of 3 must agree
sync_interval_seconds=30
)
local_registry.join_federation(federation)
Cross-Organization Trust
# Trust an external organization's registry
local_registry.add_trusted_issuer(
issuer_id="partner-org",
public_key="partner-public-key...",
trust_level=TrustLevel.LOW, # External agents get LOW by default
capabilities=["read_shared_data"],
namespace="partner:*" # Prefix their agent IDs
)
# Verify message from partner's agent
result = local_registry.verify_message(partner_signed_message)
# {
# "signature_valid": True,
# "issuer": "partner-org",
# "trust_level": TrustLevel.LOW,
# "namespace": "partner:agent-1"
# }
Trust Gossip Protocol
# Enable gossip for revocation propagation
local_registry.enable_gossip(
peers=[
"registry-node-2:7946",
"registry-node-3:7946"
],
gossip_interval_ms=500,
propagation_factor=3
)
# Revocations automatically propagate across network
# within seconds, even in large deployments
# Monitor gossip health
health = local_registry.gossip_health()
# {
# "connected_peers": 15,
# "avg_propagation_ms": 120,
# "last_sync": "2024-01-15T10:30:00Z"
# }
Integration with KernelSpace
IATP integrates seamlessly with the Agent OS KernelSpace for comprehensive agent governance including identity verification in policies.
Policy-Based Trust
from agent_os import KernelSpace
from agent_os.iatp import TrustRegistry, TrustLevel
# Initialize kernel with IATP integration
kernel = KernelSpace(
trust_registry=TrustRegistry(backend="redis"),
require_signatures=True, # All agent actions must be signed
min_trust_level=TrustLevel.LOW
)
# Define trust-aware policies
kernel.add_policy({
"name": "financial-operations",
"rules": [
{
"action": "transfer_funds",
"require": {
"trust_level": "HIGH",
"capabilities": ["financial_admin"],
"signature": "required"
}
},
{
"action": "view_balance",
"require": {
"trust_level": "LOW",
"signature": "required"
}
}
]
})
Signed Agent Actions
from agent_os.iatp import AgentIdentity
# Agent with identity
agent = AgentIdentity.create("finance-bot")
kernel.register_agent(agent)
@kernel.action("transfer_funds")
async def transfer(request: SignedRequest):
# Request is automatically verified by kernel
# Trust level and capabilities are checked
# Access verified identity info
print(request.signer.agent_id)
print(request.signer.trust_level)
print(request.signer.capabilities)
# Perform transfer
return await execute_transfer(request.payload)
# All actions are automatically signed
result = await kernel.execute(
agent=agent,
action="transfer_funds",
params={"amount": 1000, "to": "vendor-123"}
)
Audit Trail Integration
# IATP + EMK for complete audit trails
from agent_os.emk import Memory
kernel = KernelSpace(
trust_registry=TrustRegistry(),
memory=Memory(immutable=True)
)
# All signed actions are logged with cryptographic proof
# Query audit trail with signature verification
audit_log = await kernel.memory.query(
filter={"action": "transfer_funds"},
verify_signatures=True # Re-verify all signatures
)
for entry in audit_log:
print(f"{entry.timestamp}: {entry.signer} - {entry.action}")
print(f" Signature valid: {entry.signature_valid}")
print(f" Trust level at time: {entry.trust_level}")
Complete Multi-Agent Example
from agent_os import KernelSpace
from agent_os.iatp import AgentIdentity, TrustRegistry, TrustLevel, Capability
from agent_os.amb import MessageBus
from agent_os.emk import Memory
# Initialize infrastructure
registry = TrustRegistry(backend="redis")
bus = MessageBus(backend="redis")
memory = Memory(backend="postgres")
kernel = KernelSpace(
trust_registry=registry,
message_bus=bus,
memory=memory,
policy="strict"
)
# Create agents with identities
coordinator = AgentIdentity.create("coordinator")
worker_1 = AgentIdentity.create("worker-1")
worker_2 = AgentIdentity.create("worker-2")
# Register with trust levels
registry.register(coordinator, TrustLevel.HIGH, ["coordinate", "delegate"])
registry.register(worker_1, TrustLevel.MEDIUM, ["process_data"])
registry.register(worker_2, TrustLevel.MEDIUM, ["process_data"])
# Coordinator delegates work with capability
@kernel.agent(coordinator)
async def coordinate_work(task):
# Create capability for this specific task
task_capability = Capability.create(
issuer=coordinator,
subject=worker_1.agent_id,
actions=["process_data"],
resources=[f"task:{task.id}/*"],
valid_until=task.deadline
)
# Send signed task with capability
await bus.publish(
topic="tasks",
message=coordinator.sign({
"task_id": task.id,
"data": task.data,
"capability": task_capability.to_dict()
})
)
# Worker processes with verified identity
@kernel.agent(worker_1)
async def process_work(signed_message):
# Kernel automatically verifies signature and capability
task = signed_message.payload
result = await process_data(task["data"])
# Sign and return result
return worker_1.sign({
"task_id": task["task_id"],
"result": result,
"processed_by": worker_1.agent_id
})
# Run the multi-agent system
await kernel.run()