Managing Agents
Agents are AI systems with cryptographic identities registered in CertusOrdo.
What is an Agent?
An agent represents an autonomous AI system that can:
- Authenticate with your systems
- Execute operations within defined scopes
- Have its actions logged and audited
- Be suspended or revoked if needed
Each agent has:
| Property | Description |
|---|---|
id |
Unique identifier (UUID) |
name |
Human-readable name |
public_key |
Ed25519 public key |
secret |
Authentication credential (shown once) |
scopes |
Permitted operations |
status |
active, suspended, or revoked |
Creating Agents
from certusrodo import CertusOrdoClient
client = CertusOrdoClient(api_key="aa_your_api_key")
# Create a new agent
agent = client.agents.create(
name="payment-processor",
scopes=["payments:read", "payments:write"]
)
print(f"Agent ID: {agent.id}")
print(f"Public Key: {agent.public_key}")
print(f"Secret: {agent.secret}") # Save this immediately!
Save the Secret
The agent secret is only returned once during creation. Store it securely—you cannot retrieve it later.
Agent Naming Conventions
Use descriptive, consistent names:
# ✅ Good naming
agent = client.agents.create(name="invoice-processor-prod")
agent = client.agents.create(name="customer-support-agent-v2")
agent = client.agents.create(name="data-sync-staging")
# ❌ Avoid
agent = client.agents.create(name="agent1")
agent = client.agents.create(name="test")
Defining Scopes
Scopes control what an agent can do. Follow the principle of least privilege:
# Read-only agent
reader = client.agents.create(
name="report-generator",
scopes=["data:read", "reports:read"]
)
# Full access agent (use sparingly)
admin = client.agents.create(
name="admin-agent",
scopes=["data:read", "data:write", "data:delete", "admin:manage"]
)
Scope Naming Patterns
resource:action
Examples:
- payments:read
- payments:write
- users:delete
- reports:generate
- transactions:rollback
Listing Agents
# Get all agents in your organization
agents = client.agents.list()
for agent in agents:
print(f"{agent.name}: {agent.status}")
# Filter by status
active_agents = client.agents.list(status="active")
Getting Agent Details
agent = client.agents.get("agent-uuid-here")
print(f"Name: {agent.name}")
print(f"Status: {agent.status}")
print(f"Scopes: {agent.scopes}")
print(f"Created: {agent.created_at}")
print(f"Last Auth: {agent.last_auth_at}")
Agent Lifecycle
┌──────────┐ ┌───────────┐ ┌─────────┐
│ CREATE │────>│ ACTIVE │────>│ REVOKED │
└──────────┘ └─────┬─────┘ └─────────┘
│
│ suspend
▼
┌───────────┐
│ SUSPENDED │
└───────────┘
Suspending an Agent
Temporarily disable an agent (can be reactivated):
# Suspend - agent can no longer authenticate
client.agents.suspend(agent.id)
# Check status
agent = client.agents.get(agent.id)
print(agent.status) # "suspended"
# Reactivate later
client.agents.activate(agent.id)
Revoking an Agent
Permanently disable an agent (cannot be reactivated):
# Revoke - permanent, cannot be undone
client.agents.revoke(agent.id)
# Agent can no longer authenticate
# All active tokens are invalidated
Revocation is Permanent
Revoking an agent cannot be undone. The agent's tokens are immediately invalidated and it can never authenticate again.
Rotating Agent Credentials
If an agent's secret is compromised:
# 1. Revoke the compromised agent immediately
client.agents.revoke(compromised_agent.id)
# 2. Create a new agent with fresh credentials
new_agent = client.agents.create(
name=f"{compromised_agent.name}-rotated",
scopes=compromised_agent.scopes
)
# 3. Update your systems to use the new credentials
Agent Metadata
Track additional information with metadata:
agent = client.agents.create(
name="data-processor",
scopes=["data:read", "data:write"],
metadata={
"environment": "production",
"team": "data-engineering",
"version": "1.2.0"
}
)
Best Practices
1. One Agent Per Service
# ✅ Good - separate agents for separate services
payment_agent = client.agents.create(name="payment-service")
email_agent = client.agents.create(name="email-service")
# ❌ Bad - shared agent
shared_agent = client.agents.create(name="all-services")
2. Environment Separation
# Separate agents for each environment
dev_agent = client.agents.create(name="processor-dev", scopes=["read"])
staging_agent = client.agents.create(name="processor-staging", scopes=["read", "write"])
prod_agent = client.agents.create(name="processor-prod", scopes=["read", "write"])
3. Regular Audits
# Periodically review and clean up unused agents
agents = client.agents.list()
for agent in agents:
if agent.last_auth_at is None:
print(f"Never used: {agent.name}")
elif (datetime.now() - agent.last_auth_at).days > 90:
print(f"Inactive 90+ days: {agent.name}")
Error Handling
from certusrodo import CertusOrdoClient, NotFoundError, ValidationError
client = CertusOrdoClient(api_key="aa_your_key")
try:
agent = client.agents.get("non-existent-id")
except NotFoundError:
print("Agent not found")
try:
agent = client.agents.create(name="", scopes=[])
except ValidationError as e:
print(f"Invalid input: {e}")
Next Steps
- Authentication Guide - Authenticate your agents
- Sessions Guide - Create bounded operations
- API Reference - Full endpoint documentation