oas-document
W3C DID Document implementation with OAS extensions: builder pattern, conformance levels, lifecycle management, verification methods, service endpoints, lineage sections, and document proofs.
Installation
[dependencies]
oas-document = "1.0"
Quick Start
use oas_document::{DocumentBuilder, ConformanceLevel, LifecycleStatus, ServiceEndpoint};
use oas_crypto::OasKeyPair;
let keypair = OasKeyPair::generate();
let doc = DocumentBuilder::new("did:oas:example:agent:analyzer", "agent")
.controller("did:oas:example:hmr:alice")
.add_verification_method(&keypair)
.conformance_level(ConformanceLevel::L1)
.lifecycle_status(LifecycleStatus::Active)
.name("Analyzer Agent")
.description("An agent that analyzes data")
.add_service(ServiceEndpoint {
id: "did:oas:example:agent:analyzer#api".to_string(),
service_type: "AgentAPI".to_string(),
service_endpoint: "https://api.example.com/analyzer".to_string(),
})
.build_and_sign(&keypair, "2026-01-15T00:00:00Z")
.unwrap();
assert_eq!(doc.id, "did:oas:example:agent:analyzer");
assert!(doc.proof.is_some());
API Reference
OasDocument
pub struct OasDocument {
pub context: Vec<String>,
pub id: String,
pub controller: Option<String>,
pub verification_method: Vec<VerificationMethod>,
pub authentication: Vec<String>,
pub assertion_method: Vec<String>,
pub capability_invocation: Vec<String>,
pub capability_delegation: Vec<String>,
pub service: Vec<ServiceEndpoint>,
pub oas_version: String,
pub kind: String,
pub name: Option<String>,
pub description: Option<String>,
pub lineage: Option<LineageSection>,
pub conformance_level: Option<ConformanceLevel>,
pub lifecycle_status: Option<LifecycleStatus>,
pub sequence: Option<u64>,
pub metadata: Option<DocumentMetadata>,
pub proof: Option<DocumentProof>,
pub revoked: Option<bool>,
pub revoked_at: Option<String>,
}
impl OasDocument {
pub fn default_context() -> Vec<String>
pub fn is_root(&self) -> bool
pub fn is_revoked(&self) -> bool
pub fn primary_public_key_multibase(&self) -> Option<&str>
pub fn find_verification_method(&self, id_or_fragment: &str) -> Option<&VerificationMethod>
}
DocumentBuilder
pub struct DocumentBuilder { }
impl DocumentBuilder {
pub fn new(id: &str, kind: &str) -> Self
pub fn controller(self, controller: &str) -> Self
pub fn add_verification_method(self, keypair: &OasKeyPair) -> Self
pub fn conformance_level(self, level: ConformanceLevel) -> Self
pub fn name(self, name: &str) -> Self
pub fn description(self, description: &str) -> Self
pub fn lineage(self, lineage: LineageSection) -> Self
pub fn lifecycle_status(self, status: LifecycleStatus) -> Self
pub fn sequence(self, seq: u64) -> Self
pub fn add_service(self, service: ServiceEndpoint) -> Self
pub fn build_and_sign(
self,
signing_keypair: &OasKeyPair,
created: &str,
) -> Result<OasDocument, DocumentError>
}
ConformanceLevel
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ConformanceLevel {
L0,
L1,
L2,
}
impl ConformanceLevel {
pub fn as_str(&self) -> &'static str }
LifecycleStatus
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum LifecycleStatus {
Nascent, Active, Dormant, Suspended, Terminated, Archived, }
impl LifecycleStatus {
pub fn as_str(&self) -> &'static str
}
VerificationMethod
pub const VERIFICATION_METHOD_TYPE: &str = "Ed25519VerificationKey2020";
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VerificationMethod {
pub id: String,
pub method_type: String,
pub controller: String,
pub public_key_multibase: String,
}
impl VerificationMethod {
pub fn new(did: &str, key_num: u32, public_key_multibase: &str) -> Self
pub fn key_id(&self) -> &str
}
ServiceEndpoint
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceEndpoint {
pub id: String,
pub service_type: String,
pub service_endpoint: String,
}
LineageSection
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LineageSection {
pub human_root_did: String,
pub creator_did: String,
pub generation: u32,
pub derivation_proof: Option<AgentLineageProof>,
pub human_root_chain: Vec<String>,
}
DocumentProof
pub const DOCUMENT_PROOF_TYPE: &str = "Ed25519Signature2020";
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DocumentProof {
pub proof_type: String,
pub created: String,
pub verification_method: String,
pub proof_purpose: String,
pub proof_value: String,
}
impl DocumentProof {
pub fn generate(
document_json: &serde_json::Value,
keypair: &OasKeyPair,
verification_method_id: &str,
created: &str,
) -> Result<Self, DocumentError>
pub fn verify(
&self,
document_json: &serde_json::Value,
public_key_bytes: &[u8],
) -> Result<(), DocumentError>
}
GovernanceSection (ENR entities only)
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct GovernanceSection {
pub current_mhr: String, pub epoch: u64, pub transitions: Vec<GovernanceTransition>,
pub policy: GovernancePolicy,
}
pub struct GovernanceTransition {
pub from: Option<String>, pub to: String, pub epoch: u64,
pub proof: GovernanceTransitionProof,
}
pub struct GovernanceTransitionProof {
pub proof_type: String, pub mhr_threshold_signature: String, pub timestamp: String, }
pub struct GovernancePolicy {
pub transition_requires: String, pub signing_key_rotation_requires: String, pub max_transitions_per_day: u32, pub timelock_hours: u32, }
DocumentMetadata
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DocumentMetadata {
pub created: String,
pub updated: String,
pub version: u64,
}
Constants
pub const OAS_CONTEXT: &str = "https://openagent.id/ns/oas/v1";
pub const DID_CONTEXT: &str = "https://www.w3.org/ns/did/v1";
pub const ED25519_CONTEXT: &str = "https://w3id.org/security/suites/ed25519-2020/v1";
pub const OAS_VERSION: &str = "1.0.0";
Error Type
#[derive(Debug, Error)]
pub enum DocumentError {
#[error("missing required field: {field}")]
MissingField { field: String },
#[error("invalid field value: {field}: {reason}")]
InvalidField { field: String, reason: String },
#[error("serialization error: {0}")]
Serialization(#[from] serde_json::Error),
#[error("crypto error: {0}")]
Crypto(#[from] oas_crypto::CryptoError),
#[error("DID error: {0}")]
Did(#[from] oas_did::DidError),
#[error("proof generation failed: {reason}")]
ProofGeneration { reason: String },
#[error("proof verification failed: {reason}")]
ProofVerification { reason: String },
#[error("invalid proof: {reason}")]
InvalidProof { reason: String },
#[error("invalid context: {reason}")]
InvalidContext { reason: String },
#[error("document error: {reason}")]
Other { reason: String },
}
Dependencies
| Crate |
Version |
Purpose |
oas-crypto |
workspace |
Signing, encoding, JCS |
oas-did |
workspace |
DID parsing and validation |
serde |
1.0 |
Serialization with derive |
serde_json |
1.0 |
JSON support |
chrono |
0.4 |
Timestamp handling |
thiserror |
2.0 |
Error derive macros |
License
Copyright © 2026 L1fe Labs, Inc.
Licensed under the MIT license.