Skip to content

Latest commit

 

History

History
407 lines (317 loc) · 9.71 KB

File metadata and controls

407 lines (317 loc) · 9.71 KB

Use Case: Manage Identity Across Multiple Agents

Time: 30 minutes Prerequisites: Docker, Docker Compose

Problem

You have a team running multiple AI agents across different machines. Each agent needs its own identity, but you need centralized audit logging, policy management, and OIDC integration -- not isolated local files on each developer's laptop.

Step 1: Deploy AIM Server

Pull the images:

docker pull opena2a/aim-server
docker pull opena2a/aim-dashboard

Create docker-compose.yml:

version: "3.8"
services:
  aim-server:
    image: opena2a/aim-server:latest
    ports:
      - "8080:8080"
    environment:
      - DATABASE_URL=postgres://aim:aim@db:5432/aim
      - JWT_SECRET=change-this-to-a-random-value
    depends_on:
      - db

  aim-dashboard:
    image: opena2a/aim-dashboard:latest
    ports:
      - "3000:3000"
    environment:
      - API_URL=http://aim-server:8080

  db:
    image: postgres:16
    environment:
      - POSTGRES_USER=aim
      - POSTGRES_PASSWORD=aim
      - POSTGRES_DB=aim
    volumes:
      - aim-data:/var/lib/postgresql/data

volumes:
  aim-data:

Start the stack:

docker compose up -d

Expected output:

[+] Running 3/3
 - Container aim-db-1          Started
 - Container aim-aim-server-1  Started
 - Container aim-aim-dashboard-1 Started

Verify the server is running:

curl http://localhost:8080/health

Expected output:

{"status": "healthy", "version": "1.0.0", "database": "connected"}

The dashboard is available at http://localhost:3000.

Step 2: Register Agents

Register your first agent against the server:

opena2a identity create --name data-processor --server http://localhost:8080

Expected output:

Agent created:
  ID:         aim_9c4b2e1f
  Name:       data-processor
  Public Key: ed25519:k3Lm...nP7Q
  Server:     http://localhost:8080
  Stored:     ~/.opena2a/aim-core/identities/data-processor.json

Register a second agent:

opena2a identity create --name code-reviewer --server http://localhost:8080

Expected output:

Agent created:
  ID:         aim_2d8f5a3c
  Name:       code-reviewer
  Public Key: ed25519:r9Wj...tY2X
  Server:     http://localhost:8080
  Stored:     ~/.opena2a/aim-core/identities/code-reviewer.json

Step 3: Centralized Audit Log

When agents are connected to a server, all audit events are sent to the central PostgreSQL database. Query them via the API:

curl http://localhost:8080/api/v1/audit?limit=20

Expected output:

{
  "events": [
    {
      "id": "evt_a1b2c3",
      "agentId": "aim_9c4b2e1f",
      "agentName": "data-processor",
      "action": "identity:create",
      "target": "data-processor",
      "result": "allowed",
      "timestamp": "2026-03-16T14:00:00Z",
      "hash": "sha256:f8a1..."
    },
    {
      "id": "evt_d4e5f6",
      "agentId": "aim_2d8f5a3c",
      "agentName": "code-reviewer",
      "action": "identity:create",
      "target": "code-reviewer",
      "result": "allowed",
      "timestamp": "2026-03-16T14:01:00Z",
      "hash": "sha256:c2d4..."
    }
  ],
  "total": 2,
  "limit": 20
}

Filter by agent:

curl http://localhost:8080/api/v1/audit?agentId=aim_9c4b2e1f&limit=50

Step 4: OIDC Integration

AIM Server includes an OAuth 2.0 / OIDC token endpoint for machine-to-machine authentication. Agents can request tokens that other services verify.

Configure your identity provider in the server environment:

environment:
  - OIDC_ISSUER=https://auth.example.com
  - OIDC_CLIENT_ID=aim-server
  - OIDC_CLIENT_SECRET=your-client-secret

Request a token for an agent:

curl -X POST http://localhost:8080/api/v1/token \
  -H "Content-Type: application/json" \
  -d '{"agentId": "aim_9c4b2e1f", "scope": "db:read api:call"}'

Expected output:

{
  "accessToken": "eyJhbGciOiJFZERTQSIs...",
  "tokenType": "Bearer",
  "expiresIn": 3600,
  "scope": "db:read api:call"
}

Other services verify the token against the AIM Server's JWKS endpoint at http://localhost:8080/.well-known/jwks.json.

Step 5: Fleet Overview via Dashboard

Open http://localhost:3000 in your browser. The dashboard shows:

  • Agent inventory -- all registered agents with trust scores
  • Audit timeline -- real-time event stream across all agents
  • Policy status -- which agents have policies loaded, any violations
  • Trust trends -- score history per agent over time

Option B: SDK Approach

If you prefer to manage fleet identities programmatically instead of through the CLI, use the TypeScript or Python SDKs with the server parameter.

TypeScript

npm install @opena2a/aim-core
import { AIMCore } from '@opena2a/aim-core';

// Connect to your AIM Server
const dataProcessor = new AIMCore({
  agentName: 'data-processor',
  serverUrl: 'http://localhost:8080'
});

const codeReviewer = new AIMCore({
  agentName: 'code-reviewer',
  serverUrl: 'http://localhost:8080'
});

// Create identities (registered on the server)
const dpIdentity = dataProcessor.getIdentity();
console.log('Data Processor:', dpIdentity.agentId);

const crIdentity = codeReviewer.getIdentity();
console.log('Code Reviewer:', crIdentity.agentId);

// Save policies per agent
dataProcessor.savePolicy({
  version: '1.0',
  defaultAction: 'deny',
  rules: [
    { capability: 'db:read', action: 'allow' },
    { capability: 'api:call', action: 'allow' },
    { capability: 'db:delete', action: 'deny' },
    { capability: 'file:execute', action: 'deny' }
  ]
});

codeReviewer.savePolicy({
  version: '1.0',
  defaultAction: 'deny',
  rules: [
    { capability: 'file:read', action: 'allow' },
    { capability: 'api:call', action: 'allow' },
    { capability: 'db:write', action: 'deny' },
    { capability: 'db:delete', action: 'deny' }
  ]
});

// Log events (sent to the central server)
dataProcessor.logEvent({
  action: 'db:read',
  target: 'customers',
  result: 'allowed',
  plugin: 'data-processor'
});

// Calculate trust (server-side with history)
const dpTrust = dataProcessor.calculateTrust();
console.log(`Data Processor Trust: ${dpTrust.overall}`);

const crTrust = codeReviewer.calculateTrust();
console.log(`Code Reviewer Trust: ${crTrust.overall}`);

Expected output:

Data Processor: aim_9c4b2e1f
Code Reviewer: aim_2d8f5a3c
Data Processor Trust: 0.72
Code Reviewer Trust: 0.68

Python

pip install -e sdk/python/
from aim_sdk import secure, register_agent, AIMClient, AgentType

# One-line registration (recommended)
data_processor = secure(
    name="data-processor",
    capabilities=["db:read", "api:call"],
    agent_type=AgentType.LANGCHAIN,
    aim_url="http://localhost:8080",
    api_key="your-api-key"
)

code_reviewer = secure(
    name="code-reviewer",
    capabilities=["file:read", "api:call"],
    agent_type=AgentType.CLAUDE,
    aim_url="http://localhost:8080",
    api_key="your-api-key"
)

print(f"Data Processor: {data_processor.agent_id}")
print(f"Code Reviewer: {code_reviewer.agent_id}")

# Manual client for existing agents
client = AIMClient(
    agent_id="aim_9c4b2e1f",
    aim_url="http://localhost:8080",
    api_key="your-api-key"
)

Expected output:

Data Processor: aim_9c4b2e1f
Code Reviewer: aim_2d8f5a3c

Java

<dependency>
    <groupId>org.opena2a</groupId>
    <artifactId>aim-sdk</artifactId>
    <version>1.0.0</version>
</dependency>
import org.opena2a.aim.client.AIMClient;
import org.opena2a.aim.client.AgentType;
import java.util.List;

// Builder pattern for manual client
AIMClient client = AIMClient.builder()
    .baseUrl("http://localhost:8080")
    .apiKey("your-api-key")
    .build();

// One-line registration
var dataProcessor = AIMClient.secure("data-processor",
    List.of("db:read", "api:call"),
    AgentType.LANGCHAIN);

var codeReviewer = AIMClient.secure("code-reviewer",
    List.of("file:read", "api:call"),
    AgentType.CLAUDE);

System.out.println("Data Processor: " + dataProcessor.getAgentId());
System.out.println("Code Reviewer: " + codeReviewer.getAgentId());

Expected output:

Data Processor: aim_9c4b2e1f
Code Reviewer: aim_2d8f5a3c

When the serverUrl (TypeScript), aim_url (Python), or baseUrl (Java) parameter is set, identities and audit events are routed through the AIM Server and stored in the central PostgreSQL database. The SDKs handle authentication and local key caching automatically.

Architecture

Developer A                    Developer B
  |                              |
  opena2a CLI                    opena2a CLI
  |                              |
  +-------> AIM Server <---------+
              |
              PostgreSQL
              |
              AIM Dashboard (port 3000)
Component Local Mode Server Mode
Identity storage ~/.opena2a/aim-core/ Server + local cache
Audit log audit.jsonl (file) PostgreSQL
Policy management YAML files REST API + dashboard
Trust scoring Local calculation Server-side + history
Multi-agent Per-machine only Cross-machine fleet
OIDC tokens Not available Built-in token endpoint

What You Now Have

  • Centralized identity management for all agents in your organization
  • PostgreSQL-backed audit log queryable via REST API
  • OIDC token endpoint for machine-to-machine authentication
  • A dashboard for monitoring trust scores and audit events across the fleet

Next Steps