# SentryAgent.ai AgentIdP — Java SDK Official Java client for the [SentryAgent.ai AgentIdP](https://sentryagent.ai) — an open-source Identity Provider for AI agents built on OAuth 2.0 (RFC 6749) and aligned with the [AGNTCY](https://agntcy.org) open standard. ## Requirements - Java 17+ - A running AgentIdP server ## Installation ### Maven ```xml ai.sentryagent idp-sdk 1.0.0 ``` ## Quick Start ```java import ai.sentryagent.idp.AgentIdPClient; import ai.sentryagent.idp.models.*; AgentIdPClient client = new AgentIdPClient( "https://idp.example.com", "your-agent-client-id", "sk_live_..." ); // Register a new AI agent Agent agent = client.agents().registerAgent( RegisterAgentRequest.builder() .email("screener@example.com") .agentType("screener") .version("1.0.0") .capabilities(List.of("read", "classify")) .owner("platform-team") .deploymentEnv("production") .build() ); System.out.println("Registered: " + agent.getAgentId()); ``` ## Authentication OAuth 2.0 Client Credentials are managed automatically. Tokens are cached and refreshed 60 seconds before expiry. The `TokenManager` is thread-safe. ```java // Custom scope (optional — defaults to all four scopes) AgentIdPClient client = new AgentIdPClient( "https://idp.example.com", "my-client-id", "my-client-secret", "agents:read agents:write" ); ``` ## Agent Registry ```java // Register Agent agent = client.agents().registerAgent( RegisterAgentRequest.builder() .email("...").agentType("screener").version("1.0.0") .capabilities(List.of("read")).owner("team").deploymentEnv("production") .build()); // List (with optional filters) PaginatedAgents agents = client.agents().listAgents( ListAgentsParams.builder().status("active").page(1).limit(20).build()); // Get by ID Agent agent = client.agents().getAgent("agent-uuid"); // Partial update Agent updated = client.agents().updateAgent("agent-uuid", UpdateAgentRequest.builder().version("2.0.0").build()); // Decommission (permanent) client.agents().decommissionAgent("agent-uuid"); ``` ## Credential Management ```java // Generate (returns one-time ClientSecret) CredentialWithSecret cred = client.credentials().generateCredential("agent-uuid"); System.out.println(cred.getClientSecret()); // store this — shown only once // List PaginatedCredentials creds = client.credentials().listCredentials("agent-uuid", 1, 20); // Rotate CredentialWithSecret newCred = client.credentials().rotateCredential("agent-uuid", "cred-uuid"); // Revoke Credential revoked = client.credentials().revokeCredential("agent-uuid", "cred-uuid"); ``` ## Token Operations ```java // Introspect (RFC 7662) IntrospectResponse result = client.tokens().introspectToken("access-token-to-check"); if (result.isActive()) { System.out.println("Token belongs to: " + result.getSub()); } // Revoke client.tokens().revokeToken("access-token-to-revoke"); ``` ## Audit Log ```java // Query with filters PaginatedAuditEvents events = client.audit().queryAuditLog( QueryAuditParams.builder() .agentId("agent-uuid") .action("token.issued") .outcome("success") .fromDate("2026-01-01") .toDate("2026-01-31") .page(1).limit(50) .build()); // Get single event AuditEvent event = client.audit().getAuditEvent("event-uuid"); ``` ## Async Methods Every sync method has an async counterpart returning `CompletableFuture`: ```java CompletableFuture future = client.agents().getAgentAsync("uuid-1"); future.thenAccept(agent -> System.out.println(agent.getAgentId())); // Compose multiple async calls client.agents().getAgentAsync("uuid-1") .thenCompose(agent -> client.credentials().generateCredentialAsync(agent.getAgentId())) .thenAccept(cred -> System.out.println("New secret: " + cred.getClientSecret())); ``` ## Error Handling All errors are thrown as `AgentIdPException` (extends `RuntimeException`): ```java try { Agent agent = client.agents().getAgent("unknown-id"); } catch (AgentIdPException ex) { System.out.printf("code=%s status=%d%n", ex.getCode(), ex.getHttpStatus()); // e.g. code=AgentNotFoundError status=404 } ``` | Method | Type | Description | |------------------|--------------------------|-------------------------------------------------| | `getCode()` | `String` | Machine-readable error code | | `getMessage()` | `String` | Human-readable description | | `getHttpStatus()`| `int` | HTTP status code (0 for network/build errors) | | `getDetails()` | `Map` | Optional structured context from the API | ## API Coverage | Endpoint | Method | SDK Method | |--------------------------------------------------|--------|-----------------------------------------| | POST /api/v1/agents | POST | `agents().registerAgent()` | | GET /api/v1/agents | GET | `agents().listAgents()` | | GET /api/v1/agents/:id | GET | `agents().getAgent()` | | PATCH /api/v1/agents/:id | PATCH | `agents().updateAgent()` | | DELETE /api/v1/agents/:id | DELETE | `agents().decommissionAgent()` | | POST /api/v1/agents/:id/credentials | POST | `credentials().generateCredential()` | | GET /api/v1/agents/:id/credentials | GET | `credentials().listCredentials()` | | POST /api/v1/agents/:id/credentials/:cid/rotate | POST | `credentials().rotateCredential()` | | DELETE /api/v1/agents/:id/credentials/:cid | DELETE | `credentials().revokeCredential()` | | POST /api/v1/token | POST | (TokenManager — automatic) | | POST /api/v1/token/introspect | POST | `tokens().introspectToken()` | | POST /api/v1/token/revoke | POST | `tokens().revokeToken()` | | GET /api/v1/audit | GET | `audit().queryAuditLog()` | | GET /api/v1/audit/:id | GET | `audit().getAuditEvent()` | ## License Apache 2.0 — see [LICENSE](../LICENSE).