Java SDK Integration
The official Java SDK for AIM provides one-line registration against a running AIM server, AspectJ annotations, and JSON Lines security logging. Suited for Spring Boot and LangChain4j applications.
No proxy overhead
The SDK doesn't intercept your agent's traffic. @SecureAction and performAction() report actions to AIM while your agent communicates directly with target systems. MCP discovery runs in background threads. Zero latency added to agent↔target communication.
System requirements
Prerequisites
- • Java 17+ (LTS recommended)
- • Maven to build the SDK, and Maven or Gradle in your project
- • BouncyCastle - Ed25519 cryptography
- • OkHttp - HTTP client
- • Jackson - JSON processing
You do not declare BouncyCastle, OkHttp or Jackson yourself. The SDK brings them in at the versions pinned in sdk/java/pom.xml. If your build manages any of them itself, keep each one at or above the version in that file.
Installation
Build the SDK from source
The Java SDK is not published to Maven Central. Clone the AIM repository and build it: mvn install compiles the SDK, runs its tests and installs it in your local Maven repository.
git clone https://github.com/opena2a-org/agent-identity-management.git
cd agent-identity-management/sdk/java
mvn installMaven
Add a dependency to your pom.xml with the groupId, artifactId and version declared at the top of sdk/java/pom.xml. Maven resolves it from your local repository.
Gradle
Gradle reads your local Maven repository only when you add it. Add mavenLocal() to your repositories, then declare the dependency with the coordinates from sdk/java/pom.xml.
repositories {
mavenLocal()
mavenCentral()
}Quick start
One line registration
import org.opena2a.aim.client.AIMClient;
import org.opena2a.aim.client.AgentType;
import java.util.Arrays;
import java.util.Map;
// ══════════════════════════════════════════════════════════════════════════
// AGENT REGISTRATION - One Line Setup!
// ══════════════════════════════════════════════════════════════════════════
AIMClient agent = AIMClient.builder("my-ai-assistant").build();
// Or with full configuration
AIMClient agent = AIMClient.builder("my-ai-assistant")
.agentType(AgentType.LANGCHAIN)
.capabilities(Arrays.asList("db:read", "api:call"))
.talksTo(Arrays.asList("filesystem", "github"))
.description("Customer support AI agent")
.tags(Arrays.asList("production", "gpt-4"))
.metadata(Map.of("model", "gpt-4", "team", "support"))
.build();
// ══════════════════════════════════════════════════════════════════════════
// TRACK ACTIONS & RISKS - Log all agent activities in AIM
// ══════════════════════════════════════════════════════════════════════════
// Basic action with lambda
User user = agent.performAction("db:read", "users_table", () -> {
return userRepository.findById(userId);
});
// With risk level
PaymentResult payment = agent.performAction(
"payment:process",
"stripe_api",
RiskLevel.HIGH,
() -> paymentService.process(request)
);
// Get agent details
Map<String, Object> details = agent.getAgentDetails();
System.out.println("Trust Score: " + details.get("trustScore"));@SecureAction annotations
Use AspectJ annotations for declarative security. The SDK automatically verifies capabilities before method execution.
import org.opena2a.aim.annotations.SecureAction;
import org.opena2a.aim.client.RiskLevel;
public class UserService {
// Low-risk: read operations
@SecureAction(capability = "db:read", resource = "users_table")
public User getUserById(String id) {
return userRepository.findById(id);
}
// High-risk: payment processing (RiskLevel is an enum)
@SecureAction(
capability = "payment:process",
resource = "stripe",
riskLevel = RiskLevel.HIGH
)
public PaymentResult processPayment(PaymentRequest request) {
return paymentService.process(request);
}
// Critical-risk with JIT access (requires admin approval)
@SecureAction(
capability = "db:delete",
resource = "users_table",
riskLevel = RiskLevel.CRITICAL,
jitAccess = true,
jitTimeout = 300 // 5 minutes to approve
)
public void deleteUser(String userId) {
// Execution pauses until admin approval
userRepository.deleteById(userId);
}
}Spring Boot configuration
import org.opena2a.aim.annotations.SecureActionAspect;
import org.opena2a.aim.client.AIMClient;
@Configuration
@EnableAspectJAutoProxy
public class SecurityConfig {
@Bean
public AIMClient aimClient() {
return AIMClient.builder("my-spring-agent").build();
}
@PostConstruct
public void configureAspect() {
SecureActionAspect.setClient(aimClient());
}
}Enterprise security features
The Java SDK includes security event logging, pattern-based risk detection, MCP drift detection and ABOM generation.
SecurityLogger - JSON Lines security logging
Writes security events as JSON Lines, one JSON object per line, for a log shipper to forward to a SIEM.
import org.opena2a.aim.security.SecurityLogger;
import org.opena2a.aim.security.EventTypes;
SecurityLogger logger = SecurityLogger.getInstance();
String sessionId = logger.startSession();
// Set agent context for all subsequent logs
logger.setAgentContext(
agent.getAgentId().toString(),
agent.getAgentName(),
"user-123",
"org-456"
);
// Log authentication events (written as JSON Lines)
logger.logAuthentication(
EventTypes.Authn.TOKEN_REFRESH,
true,
"Token refreshed successfully",
Map.of("tokenId", "abc123")
);
// Log authorization events
logger.logAuthorizationEvent(
EventTypes.Authz.CAPABILITY_GRANTED,
"db:read",
"users_table",
true,
Map.of("riskLevel", "LOW")
);RiskDetector - pattern-based risk analysis
Automatic risk level detection based on capability patterns.
import org.opena2a.aim.security.RiskDetector;
import org.opena2a.aim.security.RiskLevel;
RiskDetector detector = RiskDetector.getInstance();
// Detect risk for a capability
RiskLevel level = detector.detectRisk("admin:delete");
// Returns: CRITICAL
// Risk patterns:
// api:*, file:read → LOW
// db:read, db:write → MEDIUM
// db:delete, payment:* → HIGH
// admin:*, system:* → CRITICAL
// Aggregate risk for multiple capabilities
List<String> capabilities = Arrays.asList("api:call", "db:read", "payment:process");
RiskLevel aggregate = detector.detectAggregateRisk(capabilities);
// Returns: HIGH (highest of all)
// Check if approval required
if (level.requiresApproval()) {
// Trigger JIT access workflow
}AttestationCache - MCP drift detection
Cache MCP attestations and detect capability drift (supply chain changes).
import org.opena2a.aim.mcp.AttestationCache;
import org.opena2a.aim.integrations.mcp.discovery.MCPDiscoveryResult;
import org.opena2a.aim.integrations.mcp.discovery.MCPTool;
AttestationCache cache = AttestationCache.getInstance();
// Store initial attestation
List<MCPTool> tools = Arrays.asList(
new MCPTool("read_file", "Read file contents", null),
new MCPTool("write_file", "Write to file", null)
);
MCPDiscoveryResult discovery = MCPDiscoveryResult.builder()
.serverName("filesystem-mcp")
.tools(tools)
.connectionLatencyMs(50)
.build();
cache.store("filesystem-mcp", discovery, "attestation-123");
// Later, check for drift (new tool added - possible supply chain attack!)
List<MCPTool> currentTools = Arrays.asList(
new MCPTool("read_file", "Read file contents", null),
new MCPTool("write_file", "Write to file", null),
new MCPTool("delete_file", "DELETE FILES!", null) // NEW!
);
MCPDiscoveryResult currentDiscovery = MCPDiscoveryResult.builder()
.serverName("filesystem-mcp")
.tools(currentTools)
.build();
AttestationCache.DriftReport drift = cache.detectDrift("filesystem-mcp", currentDiscovery);
if (drift.hasDrift()) {
System.out.println("ALERT: MCP capability drift detected!");
}SupplyChainReporter - ABOM generation
Generate Agent Bill of Materials (ABOM) for compliance audits. CycloneDX-compliant format.
import org.opena2a.aim.security.SupplyChainReporter;
SupplyChainReporter reporter = SupplyChainReporter.getInstance();
// Record MCP servers
reporter.recordMcpServer("filesystem-mcp", "npx @mcp/filesystem", discovery);
reporter.recordMcpServer("github-mcp", "npx @mcp/github", githubDiscovery);
// Generate ABOM (Agent Bill of Materials)
SupplyChainReporter.SBOM sbom = reporter.generateSBOM(agent.getAgentName());
System.out.println("Format: " + sbom.format); // CycloneDX
System.out.println("Components: " + sbom.componentCount);
System.out.println("Generated: " + sbom.generatedAt);
// Export for compliance audits
for (SupplyChainReporter.SBOMComponent component : sbom.components) {
System.out.println("- " + component.name + " v" + component.version);
System.out.println(" PURL: " + component.purl);
}MCP server integration
// Register MCP Server
Map<String, Object> result = agent.registerMcp(
"filesystem-mcp", // server ID
"sdk_registration", // detection method
0.85 // confidence score
);
// List MCP Servers
List<Map<String, Object>> servers = agent.listMcpServers(20);
for (Map<String, Object> server : servers) {
System.out.println(server.get("name") + ": " + server.get("status"));
}
// Attest MCP Server (cryptographic verification)
Map<String, Object> attestation = agent.attestMcp(
serverId,
"http://localhost:3001",
"filesystem-mcp",
Arrays.asList("read_file", "write_file"),
45.0 // confidence threshold
);
// Record tool usage
agent.useMcpTool(serverId, "read_file", "http://localhost:3001", "filesystem-mcp");LangChain4j integration
Wrap LangChain4j tools with AIM security verification for enterprise-grade AI applications.
import org.opena2a.aim.integration.langchain4j.AIMToolExecutor;
import org.opena2a.aim.integration.langchain4j.AIMAgentCallback;
// Create tool executor with security wrapper
AIMToolExecutor executor = new AIMToolExecutor(agent);
// Register tools with required capabilities
executor.register("search_web", "Search the web",
input -> webSearch(input), "api:call");
executor.register("read_database", "Query database",
input -> queryDatabase(input), "db:read");
executor.register("admin_override", "Admin operations",
input -> adminOp(input), "admin:override");
// Configure risk-based blocking
executor.setBlockHighRisk(true);
executor.setApprovalThreshold(RiskLevel.HIGH);
// Execute with automatic verification
try {
Object result = executor.execute("search_web", "AI safety");
// Success - capability verified
} catch (AIMToolExecutor.ToolBlockedException e) {
System.out.println("Tool blocked: " + e.getRiskLevel());
}
// Get execution metrics
Map<String, Map<String, Object>> metrics = executor.getAllMetrics();Error handling
import org.opena2a.aim.exceptions.*;
try {
agent.performAction("db:delete", "users", () -> deleteAllUsers());
} catch (ActionDeniedException e) {
System.err.println("Denied: " + e.getCapability() + " on " + e.getResource());
} catch (VerificationException e) {
System.err.println("Verification failed: " + e.getMessage());
} catch (AuthenticationException e) {
System.err.println("Auth failed: " + e.getMessage());
} catch (CredentialException e) {
System.err.println("Credential error: " + e.getMessage());
} catch (AIMException e) {
System.err.println("AIM error: " + e.getMessage());
}Risk levels
| Level | Patterns | Requires approval |
|---|---|---|
| LOW | api:*, file:read, config:read | No |
| MEDIUM | db:read, db:write, file:write | No |
| HIGH | db:delete, payment:*, user:delete | Optional (JIT) |
| CRITICAL | admin:*, system:*, *:delete_all | Yes |
Credential lookup order
- 1. Environment variables (highest priority) - AIM_URL, AIM_REFRESH_TOKEN, AIM_SDK_TOKEN_ID
- 2. Home directory - ~/.aim/sdk_credentials.json
- 3. Local directory - .aim/sdk_credentials.json
- 4. Classpath - Bundled in JAR