Time: 30 minutes Prerequisites: Docker, Docker Compose
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.
Pull the images:
docker pull opena2a/aim-server
docker pull opena2a/aim-dashboardCreate 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 -dExpected 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/healthExpected output:
{"status": "healthy", "version": "1.0.0", "database": "connected"}The dashboard is available at http://localhost:3000.
Register your first agent against the server:
opena2a identity create --name data-processor --server http://localhost:8080Expected 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:8080Expected 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
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=20Expected 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=50AIM 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-secretRequest 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.
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
If you prefer to manage fleet identities programmatically instead of through the CLI, use the TypeScript or Python SDKs with the server parameter.
npm install @opena2a/aim-coreimport { 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
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
<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.
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 |
- 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
- Enforce capabilities -- define policies for each agent in the fleet
- Embed in my app -- connect your custom agents to the server programmatically
- Deployment guide -- production deployment on AWS, Azure, GCP, and Kubernetes