Skip to content

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