Manual Integration Guide
Complete guide for integrating with AIM without using the Python SDK. This covers direct API integration, cryptographic signing, capability declaration, and MCP server registration.
When to Use Manual Integration
Manual integration is recommended when:
- You're using a language other than Python
- You need fine-grained control over the integration
- You're building a custom SDK for your organization
- You're integrating AIM into existing infrastructure
Note: The Python SDK handles all of this automatically. Use it when possible.
Choose Your Language
Step 1: Generate Base64 Public Key
Public Key Generation Guide
AIM requires Ed25519 public keys in base64 format (exactly 32 bytes). Here's how to generate them correctly:
# Generating Base64 Public Keys for AIM
## Method 1: Using OpenSSL (Recommended)
# Generate Ed25519 key pair
openssl genpkey -algorithm ed25519 -out private_key.pem
openssl pkey -in private_key.pem -pubout -out public_key.pem
# Extract raw public key bytes and convert to base64
# Note: Ed25519 public keys are exactly 32 bytes
openssl pkey -in private_key.pem -pubout -outform DER | tail -c 32 | base64
# Or extract from PEM file (removes headers and newlines)
PUBLIC_KEY=$(cat public_key.pem | grep -v "PUBLIC KEY" | tr -d '\n')
## Method 2: Using Python (nacl library)
import nacl.signing
import nacl.encoding
import base64
# Generate keypair
signing_key = nacl.signing.SigningKey.generate()
verify_key = signing_key.verify_key
# Get base64-encoded public key (32 bytes)
public_key_b64 = verify_key.encode(encoder=nacl.encoding.Base64Encoder).decode('utf-8')
print(f"Base64 public key: {public_key_b64}")
# Example output: "YXNkZmFzZGZhc2RmYXNkZmFzZGZhc2RmYXNkZmFzZGY="
## Method 3: Using Node.js
const crypto = require('crypto');
// Generate Ed25519 key pair
const { publicKey, privateKey } = crypto.generateKeyPairSync('ed25519');
// Export public key as base64 (raw 32 bytes)
const publicKeyDer = publicKey.export({ type: 'spki', format: 'der' });
// Skip the SPKI header (12 bytes) to get raw Ed25519 public key (32 bytes)
const rawPublicKey = publicKeyDer.slice(-32);
const publicKeyBase64 = rawPublicKey.toString('base64');
console.log('Base64 public key:', publicKeyBase64);
## Method 4: Using Go
import (
"crypto/ed25519"
"crypto/rand"
"encoding/base64"
)
// Generate key pair
publicKey, privateKey, _ := ed25519.GenerateKey(rand.Reader)
// Convert public key to base64 (32 bytes)
publicKeyBase64 := base64.StdEncoding.EncodeToString(publicKey)
fmt.Printf("Base64 public key: %s\n", publicKeyBase64)
## Key Format Requirements for AIM:
# MUST be exactly 32 bytes when decoded from base64
# MUST be raw Ed25519 public key bytes (not PEM, not DER with headers)
# MUST be standard base64 encoding (not URL-safe)
# Example valid format: "YXNkZmFzZGZhc2RmYXNkZmFzZGZhc2RmYXNkZmFzZGY="
## Validating Your Public Key:
# Check if your base64 public key is valid
echo "YOUR_BASE64_PUBLIC_KEY" | base64 -d | wc -c
# Should output: 32
# Verify it's valid Ed25519 format (Python)
import base64
public_key_b64 = "YOUR_BASE64_PUBLIC_KEY"
public_key_bytes = base64.b64decode(public_key_b64)
assert len(public_key_bytes) == 32, f"Invalid length: {len(public_key_bytes)} (expected 32)"
print("Valid Ed25519 public key format")Step 2: Agent Registration
Generate Keys & Register Agent
First, generate an Ed25519 key pair and register your agent with AIM:
# Step 1: Get your API key from AIM Dashboard (Settings → API Keys)
# The API key is used to authenticate the registration request
# Step 2: Register agent with AIM
# Note: AIM generates Ed25519 keys for you - no need to create them manually!
curl -X POST https://your-aim-server.com/api/v1/public/agents/register \
-H "Content-Type: application/json" \
-H "X-AIM-API-Key: your-api-key-here" \
-d '{
"name": "my-agent",
"displayName": "My Agent",
"description": "A secure AI agent for data processing",
"agentType": "custom",
"version": "1.0.0",
"repositoryUrl": "https://github.com/myorg/my-agent",
"documentationUrl": "https://docs.myorg.com/my-agent"
}'
# Response (SAVE THESE CREDENTIALS - privateKey is only returned ONCE!)
{
"agentId": "550e8400-e29b-41d4-a716-446655440000",
"name": "my-agent",
"displayName": "My Agent",
"publicKey": "MCowBQYDK2VwAyEA...",
"privateKey": "MC4CAQAwBQYDK2VwBCIEIA...",
"aimUrl": "https://your-aim-server.com",
"status": "pending",
"trustScore": 60,
"message": "Agent registered successfully. Awaiting verification."
}Step 2: Token Management
Automatic Token Refresh
Implement automatic token refresh to maintain continuous authentication:
# Ed25519 Authentication for API Calls
# SDK agents use Ed25519 signatures - no OAuth tokens needed!
# Load credentials saved during registration
AGENT_ID=$(cat .aim_credentials.json | jq -r '.agentId')
PRIVATE_KEY=$(cat .aim_credentials.json | jq -r '.privateKey')
AIM_URL=$(cat .aim_credentials.json | jq -r '.aimUrl')
# For API calls, sign your request with Ed25519
# The signature proves you control the agent's private key
# Example: Get agent details
curl -X GET "${AIM_URL}/api/v1/sdk-api/agents/${AGENT_ID}" \
-H "Content-Type: application/json" \
-H "X-Agent-ID: ${AGENT_ID}" \
-H "X-Agent-Signature: <ed25519-signature>" \
-H "X-Agent-Timestamp: $(date +%s)"
# The signature is computed over: timestamp + method + path + body
# Use the Ed25519 private key from registration to sign
# Example verification request (action tracking)
curl -X POST "${AIM_URL}/api/v1/sdk-api/verifications" \
-H "Content-Type: application/json" \
-H "X-Agent-ID: ${AGENT_ID}" \
-H "X-Agent-Signature: <ed25519-signature>" \
-H "X-Agent-Timestamp: $(date +%s)" \
-d '{
"agentId": "'"${AGENT_ID}"'",
"capability": "process_data",
"resource": "user-data",
"riskLevel": "medium",
"context": {"action": "process"}
}'Step 3: Declare Capabilities
Manual Capability Declaration
Declare what your agent can do - these are the operations it can perform:
# Manual Capability Declaration
# Method 1: During Registration
curl -X POST https://api.aim.example.com/v1/agents/register \
-H "Content-Type: application/json" \
-H "X-Agent-Signature: $SIGNATURE" \
-d '{
"name": "my-agent",
"public_key": "'$PUBLIC_KEY'",
"capabilities": [
{
"name": "text_analysis",
"description": "Analyze text for sentiment and entities",
"parameters": {
"text": {
"type": "string",
"required": true,
"description": "Text to analyze"
},
"language": {
"type": "string",
"required": false,
"default": "en",
"description": "Language code"
}
},
"returns": {
"type": "object",
"properties": {
"sentiment": "string",
"entities": "array",
"confidence": "number"
}
}
},
{
"name": "data_export",
"description": "Export data to various formats",
"parameters": {
"format": {
"type": "string",
"enum": ["json", "csv", "parquet"],
"required": true
},
"filters": {
"type": "object",
"required": false
}
}
}
]
}'
# Method 2: Update Capabilities After Registration
curl -X PUT https://api.aim.example.com/v1/agents/my-agent/capabilities \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"capabilities": [
{
"name": "new_capability",
"description": "A new capability",
"parameters": {...}
}
]
}'
# Method 3: Add Individual Capability
curl -X POST https://api.aim.example.com/v1/agents/my-agent/capabilities \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "process_image",
"description": "Process and analyze images",
"parameters": {
"image_url": "string",
"operations": "array"
}
}'Step 4: Register MCP Servers
MCP Server Registration
Register MCP servers that your agent communicates with:
# Manual MCP Server Declaration
# 1. Register MCP Server with Agent
curl -X POST https://api.aim.example.com/v1/agents/my-agent/mcp-servers \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "custom-processor",
"url": "http://localhost:8080",
"public_key": "-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
-----END PUBLIC KEY-----",
"capabilities": [
"text_processing",
"data_analysis",
"report_generation"
],
"metadata": {
"version": "1.0.0",
"protocol": "mcp-v1",
"description": "Custom data processing MCP server"
}
}'
# 2. Verify MCP Server (Cryptographic Verification)
curl -X POST https://api.aim.example.com/v1/mcp-servers/custom-processor/verify \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"challenge": "random-challenge-string",
"signature": "signature-from-mcp-server"
}'
# 3. Update MCP Server Capabilities
curl -X PATCH https://api.aim.example.com/v1/mcp-servers/custom-processor \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"capabilities": {
"add": ["new_capability"],
"remove": ["old_capability"]
}
}'
# 4. List Agent's MCP Servers
curl -H "Authorization: Bearer $ACCESS_TOKEN" \
https://api.aim.example.com/v1/agents/my-agent/mcp-serversStep 5: Cryptographic Verification
Ed25519 Signature Verification
Verify requests from AIM and sign your responses:
# Ed25519 Signature Verification
# Python implementation
import ed25519
import json
import base64
def verify_request(request):
"""Verify incoming request from AIM"""
# Extract signature from header
signature_hex = request.headers.get('X-AIM-Signature')
if not signature_hex:
return False
# Get AIM's public key (from initial setup)
aim_public_key = load_aim_public_key()
# Reconstruct the message
message = json.dumps(request.json, sort_keys=True)
# Verify signature
try:
verifying_key = ed25519.VerifyingKey(aim_public_key)
verifying_key.verify(
bytes.fromhex(signature_hex),
message.encode()
)
return True
except ed25519.BadSignatureError:
return False
def sign_response(response_data, private_key):
"""Sign outgoing response to AIM"""
# Load your private key
signing_key = ed25519.SigningKey(private_key)
# Create message
message = json.dumps(response_data, sort_keys=True)
# Sign
signature = signing_key.sign(message.encode())
return {
'data': response_data,
'signature': signature.hex()
}
# Webhook endpoint example
@app.route('/webhook', methods=['POST'])
def handle_webhook():
# Verify the request is from AIM
if not verify_request(request):
return {'error': 'Invalid signature'}, 401
# Process the request
result = process_aim_request(request.json)
# Sign and return response
signed_response = sign_response(result, private_key)
return signed_responseStep 6: Health & Monitoring
Health Checks & Heartbeats
# Health Check & Monitoring
# 1. Agent Health Check
curl -H "Authorization: Bearer $ACCESS_TOKEN" \
https://api.aim.example.com/v1/agents/my-agent/health
# Response
{
"status": "healthy",
"uptime": 86400,
"last_activity": "2024-01-20T10:30:00Z",
"trust_score": 0.92,
"capabilities_count": 5,
"mcp_servers_count": 2,
"token_expires_in": 842,
"metrics": {
"requests_total": 1523,
"requests_success": 1501,
"requests_failed": 22,
"avg_response_time": 45
}
}
# 2. Heartbeat Endpoint (Keep-Alive)
while true; do
curl -X POST https://api.aim.example.com/v1/agents/my-agent/heartbeat \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "active",
"capabilities_available": ["process_data", "analyze_text"],
"mcp_servers_connected": ["custom-processor"],
"resource_usage": {
"cpu_percent": 15.2,
"memory_mb": 256,
"connections": 5
}
}'
sleep 30 # Send heartbeat every 30 seconds
done
# 3. Metrics Reporting
curl -X POST https://api.aim.example.com/v1/agents/my-agent/metrics \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",
"metrics": {
"operations_performed": 42,
"data_processed_mb": 156.8,
"errors_encountered": 2,
"average_latency_ms": 35
}
}'Integration Checklist
Common Integration Issues
Signature Verification Failed
Ensure you're using the exact JSON string (with sorted keys) that was signed. Whitespace and key order matter.
Token Expired Errors
Implement token refresh at least 5 minutes before expiration. Handle 401 responses by refreshing tokens and retrying.
MCP Server Not Verified
Ensure the MCP server responds to verification challenges with proper Ed25519 signatures.
Rate Limiting
Implement exponential backoff. Default limits: 10 refresh/min, 1000 API calls/hour.
Security Best Practices
Key Management
- Never commit private keys to version control
- Use secure key storage (HSM, KMS, Vault)
- Rotate keys periodically
- Use different keys per environment
Token Security
- Store tokens encrypted at rest
- Use secure transport (HTTPS only)
- Implement token refresh before expiry
- Handle token rotation properly