Files
sentryagent-idp/sdk-rust
SentryAgent.ai Developer 0506bc1b8e chore(sdk-rust): add .gitignore to exclude build artifacts
Removes sdk-rust/target/ from tracking — was accidentally committed
without a Rust .gitignore in place.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 02:49:19 +00:00
..
2026-04-03 02:48:14 +00:00
2026-04-03 02:48:14 +00:00
2026-04-03 02:48:14 +00:00
2026-04-03 02:48:14 +00:00
2026-04-03 02:48:14 +00:00
2026-04-03 02:48:14 +00:00

sentryagent-idp — Rust SDK

Production-grade Rust client for the SentryAgent.ai AgentIdP API. Covers all 14 API endpoints across agent identity, OAuth 2.0 token management, credential rotation, audit logs, the public marketplace, and A2A delegation.

Features

  • Async-first — every API call is async and backed by tokio
  • Thread-safe token cache — TokenManager refreshes tokens automatically before expiry
  • Typed errors — every failure maps to a variant of AgentIdPError
  • Zero unwrap() in library code — all errors propagated with ?
  • Full //! and /// doc coverage — cargo doc --no-deps generates clean docs
  • #![deny(warnings)] enforced — zero clippy warnings

Installation

Add to your Cargo.toml:

[dependencies]
sentryagent-idp = "1.0"
tokio = { version = "1", features = ["full"] }

Environment Variables

Variable Purpose
AGENTIDP_API_URL Base URL of the AgentIdP API (e.g. https://api.sentryagent.ai)
AGENTIDP_CLIENT_ID OAuth 2.0 client identifier
AGENTIDP_CLIENT_SECRET OAuth 2.0 client secret

Quickstart

use sentryagent_idp::{AgentIdPClient, RegisterAgentRequest};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Build from environment variables.
    let client = AgentIdPClient::from_env()?;

    // Register a new agent.
    let agent = client.register_agent(RegisterAgentRequest {
        name: "my-agent".to_owned(),
        description: Some("Does useful things".to_owned()),
        agent_type: "worker".to_owned(),
        capabilities: vec!["read:data".to_owned()],
        metadata: None,
    }).await?;

    println!("Agent registered: {} (DID: {})", agent.id, agent.did);

    // Issue a scoped access token.
    let token = client.issue_token(&agent.id, &["agents:read"]).await?;
    println!("Token issued, expires in {}s", token.expires_in);

    // Clean up.
    client.delete_agent(&agent.id).await?;
    Ok(())
}

Method Reference

Agent Registry

Method Endpoint Description
register_agent(req) POST /agents Register a new agent identity
get_agent(id) GET /agents/{id} Retrieve an agent by ID
list_agents(page, per_page) GET /agents List all agents (paginated)
update_agent(id, req) PATCH /agents/{id} Partially update an agent
delete_agent(id) DELETE /agents/{id} Permanently delete an agent

OAuth 2.0

Method Endpoint Description
issue_token(agent_id, scopes) POST /oauth2/token Issue a scoped access token

Credentials

Method Endpoint Description
generate_credentials(agent_id) POST /agents/{id}/credentials Generate credentials (returns secret once)
rotate_credentials(agent_id) POST /agents/{id}/credentials/rotate Rotate credentials (invalidates previous)
revoke_credentials(agent_id, cred_id) DELETE /agents/{id}/credentials/{cred_id} Revoke a specific credential set

Audit Logs

Method Endpoint Description
list_audit_logs(filters) GET /audit-logs Query audit events with optional filters

Marketplace (unauthenticated)

Method Endpoint Description
list_public_agents(filters) GET /marketplace/agents Browse public marketplace agents
get_public_agent(id) GET /marketplace/agents/{id} Retrieve a single marketplace agent

Delegation

Method Endpoint Description
delegate(req) POST /delegation Create an A2A delegation token
verify_delegation(token) POST /delegation/verify Verify and decode a delegation token

Error Handling

All methods return Result<T, AgentIdPError>. Match on variants for fine-grained handling:

use sentryagent_idp::AgentIdPError;

match client.get_agent("unknown-id").await {
    Err(AgentIdPError::NotFound(msg)) => {
        eprintln!("Agent not found: {}", msg);
    }
    Err(AgentIdPError::RateLimited { retry_after_secs }) => {
        eprintln!("Rate limited — retry after {}s", retry_after_secs);
    }
    Err(AgentIdPError::AuthError(msg)) => {
        eprintln!("Authentication failed: {}", msg);
    }
    Err(AgentIdPError::ApiError { status, message, code }) => {
        eprintln!("API error {}: {} (code: {:?})", status, message, code);
    }
    Err(e) => eprintln!("Unexpected error: {}", e),
    Ok(agent) => println!("Found: {}", agent.name),
}

Error Variants

Variant Cause
HttpError(reqwest::Error) Network-level transport failure
ApiError { status, message, code } Non-2xx HTTP response with error body
AuthError(String) 401 or 403 — invalid credentials or insufficient scope
NotFound(String) 404 — resource does not exist
RateLimited { retry_after_secs } 429 — too many requests
ConfigError(String) Missing environment variable on from_env()
SerdeError(serde_json::Error) JSON parsing failure
DelegationError(String) Invalid or revoked delegation chain

Running Integration Tests

Integration tests are ignored by default. Set the three environment variables and run:

AGENTIDP_API_URL=https://api.sentryagent.ai \
AGENTIDP_CLIENT_ID=your-client-id \
AGENTIDP_CLIENT_SECRET=your-client-secret \
cargo test -- --ignored

Publishing to crates.io

This crate is published as sentryagent-idp version 1.0.0. To publish a new version:

# Update version in Cargo.toml, then:
cargo publish --registry crates-io

Ensure CARGO_REGISTRY_TOKEN is set to a valid crates.io API token before publishing.

License

MIT — see LICENSE for details.