Skip to content

IDProva launches April 7 — Registry packages coming at launch. Build from source now.

Rust SDK

The idprova-core crate is the reference implementation of the IDProva protocol. All other SDKs (Python, TypeScript) are thin bindings over this crate. It provides everything you need to create agent identities, issue and verify DATs, generate and validate Action Receipts, and work with the trust model.

Cargo.toml
[dependencies]
idprova-core = "0.1"

Minimum Supported Rust Version: 1.75

use idprova_core::crypto::KeyPair;
use idprova_core::aid::AidBuilder;
use idprova_core::dat::DelegationToken;
use std::time::Duration;
fn main() -> idprova_core::Result<()> {
// 1. Generate keypairs
let controller_keys = KeyPair::generate()?;
let agent_keys = KeyPair::generate()?;
// 2. Create AID
let aid = AidBuilder::new()
.id("did:idprova:example.com:my-agent")
.controller("did:idprova:example.com:alice")
.add_verification_key(agent_keys.public_key())
.model("anthropic/claude-opus-4")
.runtime("custom/v1.0")
.build()?;
println!("Created AID: {}", aid.id());
// 3. Issue delegation
let dat = DelegationToken::issue(
&controller_keys,
"did:idprova:example.com:alice",
"did:idprova:example.com:my-agent",
&["mcp:tool:*:read"],
Duration::from_secs(86400),
)?;
println!("Issued DAT: {}", dat.compact());
// 4. Verify
let verified = dat.verify(&controller_keys.public_key())?;
println!("Verified: scopes = {:?}", verified.scopes());
Ok(())
}

The crate is organised into six modules:

ModuleDescription
cryptoEd25519 key generation, signing, verification, BLAKE3/SHA-256 hashing, multibase encoding
aidAgent Identity Documents — DID parsing, W3C DID Document structure, builder pattern, metadata
datDelegation Attestation Tokens — JWS issuance, verification, scope parsing, chain validation
receiptAction Receipts — hash-chained entries, integrity verification, JSONL serialization
trustTrust Levels — L0-L4 enum, ordering, minimum checks
errorIdprovaError enum covering all error variants
use idprova_core::crypto::KeyPair;
// Generate new Ed25519 keypair
let kp = KeyPair::generate()?;
// Sign a message
let sig = kp.sign(b"hello world");
// Verify
assert!(kp.verify(b"hello world", &sig));
// Access public key
let multibase = kp.public_key_multibase(); // z6Mk...
let bytes = kp.public_key_bytes(); // [u8; 32]
// Restore from secret bytes
let kp2 = KeyPair::from_secret_bytes(&secret)?;
use idprova_core::crypto::hash;
let blake3_hash = hash::blake3(b"data"); // blake3:abcdef...
let sha256_hash = hash::sha256(b"data"); // sha256:abcdef...
use idprova_core::aid::AidBuilder;
use idprova_core::crypto::KeyPair;
let kp = KeyPair::generate()?;
let aid = AidBuilder::new()
.id("did:idprova:example.com:my-agent")
.controller("did:idprova:example.com:alice")
.name("My Agent")
.description("A research assistant")
.model("anthropic/claude-sonnet-4-5")
.runtime("rust/1.77")
.trust_level("L0")
.add_verification_key(kp.public_key())
.build()?;
// Serialize to JSON
let json = serde_json::to_string_pretty(&aid)?;
// Validate structure
aid.validate()?;
use idprova_core::dat::{DelegationToken, Scope};
use idprova_core::crypto::KeyPair;
use std::time::Duration;
let issuer_kp = KeyPair::generate()?;
// Issue a DAT
let dat = DelegationToken::issue(
&issuer_kp,
"did:idprova:example.com:alice", // issuer DID
"did:idprova:example.com:my-agent", // subject DID
&["mcp:tool:filesystem:read", "mcp:tool:filesystem:write"],
Duration::from_secs(86400), // 24 hours
)?;
// Serialize to JWS compact format
let compact = dat.compact();
// Parse and verify
let parsed = DelegationToken::from_compact(&compact)?;
parsed.verify(&issuer_kp.public_key())?;
parsed.validate_timing()?;
use idprova_core::dat::Scope;
let parent: Scope = "mcp:tool:filesystem:*".parse()?;
let child: Scope = "mcp:tool:filesystem:read".parse()?;
assert!(parent.covers(&child)); // wildcard matches
assert!(!child.covers(&parent)); // can't escalate
use idprova_core::dat::DelegationChain;
// Validate a chain of DATs
let chain = DelegationChain::new(vec![root_dat, child_dat, leaf_dat]);
chain.validate()?; // checks signatures, scope narrowing, timing
use idprova_core::receipt::ReceiptLog;
let mut log = ReceiptLog::new("did:idprova:example.com:my-agent");
// Verify chain integrity
log.verify_integrity()?;
// Access chain state
println!("Entries: {}", log.len());
println!("Last hash: {}", log.last_hash());
use idprova_core::trust::TrustLevel;
let l1 = TrustLevel::L1;
let l2 = TrustLevel::L2;
assert!(l2.meets_minimum(l1)); // L2 >= L1
assert!(l2 > l1); // Ord implemented

All operations return idprova_core::Result<T>, with errors in the IdprovaError enum:

use idprova_core::error::IdprovaError;
match result {
Err(IdprovaError::Crypto(msg)) => /* key/signature error */,
Err(IdprovaError::Aid(msg)) => /* DID/document error */,
Err(IdprovaError::Dat(msg)) => /* token/scope error */,
Err(IdprovaError::Receipt(msg)) => /* receipt/chain error */,
Err(IdprovaError::Trust(msg)) => /* trust level error */,
Err(IdprovaError::Serialization(msg)) => /* JSON error */,
Ok(value) => /* success */,
}

The crate is compiled with LTO and single codegen unit in release mode:

OperationTarget
KeyPair::generate()< 50ms
sign() / verify()< 1ms
DelegationToken::issue()< 5ms
DelegationToken::verify()< 2ms
DID resolution (with cache)< 5s