Advanced Topics
W3C DID Support
Decentralized identity integration in ZAP
W3C DID Support
ZAP implements W3C Decentralized Identifiers (DIDs) for agent identity management.
Overview
DIDs provide:
- Self-sovereign identity: Control your own identity
- No central authority: Decentralized verification
- Cryptographic binding: Identity tied to keys
- Service discovery: Endpoints in DID documents
DID Methods
ZAP supports three DID methods:
enum DidMethod {
lux @0; # Lux blockchain-anchored DID
key @1; # Self-certifying DID from cryptographic key
web @2; # DNS-based DID
}did:key
Self-certifying DIDs derived from public keys:
did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK- No blockchain required
- Instant creation
- Key is the identifier
- Best for development/testing
did:lux
Blockchain-anchored DIDs on Lux Network:
did:lux:0x1234567890abcdef...- On-chain resolution
- Updateable documents
- Staking support
- Best for production
did:web
DNS-based DIDs:
did:web:example.com- Resolved via HTTPS
- Easy web integration
- No blockchain needed
- Good for organizations
DID Document
struct DidDocument {
context @0 :List(Text); # JSON-LD context
id @1 :Text; # DID subject
controller @2 :Text; # Optional controller DID
# Verification methods (public keys)
verificationMethod @3 :List(VerificationMethod);
# Verification relationships
authentication @4 :List(Text);
assertionMethod @5 :List(Text);
keyAgreement @6 :List(Text);
capabilityInvocation @7 :List(Text);
capabilityDelegation @8 :List(Text);
# Service endpoints
service @9 :List(Service);
}Verification Methods
struct VerificationMethod {
id @0 :Text; # e.g., "did:lux:z6Mk...#keys-1"
type @1 :VerificationMethodType;
controller @2 :Text; # Controller DID
publicKeyMultibase @3 :Text; # Multibase-encoded public key
publicKeyJwk @4 :Data; # JSON Web Key (optional)
blockchainAccountId @5 :Text; # Blockchain account ID (for Lux)
}
enum VerificationMethodType {
jsonWebKey2020 @0;
multikey @1;
mlDsa65VerificationKey2024 @2; # Post-quantum
}Services
struct Service {
id @0 :Text; # e.g., "did:lux:z6Mk...#zap-agent"
type @1 :ServiceType;
serviceEndpoint @2 :ServiceEndpoint;
}
enum ServiceType {
zapAgent @0; # ZAP Agent service
didCommMessaging @1; # DID Communication
linkedDomains @2; # Linked Domains
credentialRegistry @3; # Credential Registry
}DID Registry
interface DidRegistry {
# Resolve a DID to its document
resolve @0 (request :DidResolveRequest) -> (response :DidResolveResponse);
# Create/register a new DID
create @1 (request :DidCreateRequest) -> (response :DidCreateResponse);
# Update a DID document (requires authentication)
update @2 (did :Text, document :DidDocument, signature :Data) -> (success :Bool, error :Text);
# Deactivate a DID (requires authentication)
deactivate @3 (did :Text, signature :Data) -> (success :Bool, error :Text);
# Get stake for a DID
getStake @4 (did :Text) -> (amount :UInt64);
# Set stake for a DID (requires authentication)
setStake @5 (did :Text, amount :UInt64, signature :Data) -> (success :Bool, error :Text);
}Usage Examples
Creating a DID
Rust
use zap_protocol::did::{Did, DidMethod, DidRegistry, Service, ServiceType};
// Generate ML-DSA keypair
let (public_key, private_key) = mldsa::generate_keypair();
// Connect to registry
let registry = DidRegistry::connect("zap://did-registry:9002").await?;
// Create did:key (instant, no blockchain)
let key_did = Did::new(DidMethod::Key, &public_key)?;
println!("Created: {}", key_did); // did:key:z6Mk...
// Create did:lux (blockchain-anchored)
let lux_did = registry.create(
DidMethod::Lux,
&public_key,
vec![
Service {
id: format!("{}#zap-agent", lux_did),
service_type: ServiceType::ZapAgent,
endpoint: "zap://my-agent.example.com:9000".into(),
}
]
).await?;
println!("Created: {}", lux_did); // did:lux:0x...Go
import "github.com/zap-protocol/zap-go/did"
// Generate keypair
publicKey, privateKey := mldsa.GenerateKeypair()
// Connect to registry
registry, _ := did.ConnectRegistry(ctx, "zap://did-registry:9002")
// Create did:key
keyDID := did.New(did.MethodKey, publicKey)
fmt.Println("Created:", keyDID)
// Create did:lux
luxDID, _ := registry.Create(ctx, did.MethodLux, publicKey, []did.Service{
{
ID: luxDID.String() + "#zap-agent",
Type: did.ServiceZapAgent,
Endpoint: "zap://my-agent.example.com:9000",
},
})Resolving a DID
// Resolve any DID
let doc = registry.resolve("did:lux:0x1234...").await?;
println!("Controller: {}", doc.controller);
println!("Authentication keys: {:?}", doc.authentication);
// Find ZAP agent endpoint
for service in &doc.service {
if service.service_type == ServiceType::ZapAgent {
println!("Agent endpoint: {}", service.endpoint);
}
}Updating a DID Document
// Update document
let mut doc = registry.resolve(&did).await?;
// Add new service
doc.service.push(Service {
id: format!("{}#new-service", did),
service_type: ServiceType::LinkedDomains,
endpoint: "https://example.com".into(),
});
// Sign and update
let signature = private_key.sign(&doc.serialize()?);
registry.update(&did, doc, signature).await?;Node Identity
ZAP nodes use DIDs for identification:
struct NodeIdentity {
did @0 :Did;
publicKey @1 :Data; # ML-DSA-65 public key (1952 bytes)
stake @2 :UInt64; # Staked amount (optional)
stakeRegistry @3 :Text; # Stake registry reference
}Creating Node Identity
use zap_protocol::did::NodeIdentity;
// Generate node identity
let node = NodeIdentity::generate()?;
node.save("./node-identity.key")?;
println!("Node DID: {}", node.did);
println!("Public key: {} bytes", node.public_key.len());Staking
For Lux DIDs, staking is supported:
// Get current stake
let stake = registry.get_stake(&did).await?;
println!("Current stake: {}", stake);
// Increase stake
let signature = private_key.sign(&format!("stake:{}", new_amount));
registry.set_stake(&did, new_amount, signature).await?;Stake affects:
- Agent consensus voting weight
- Ringtail party eligibility
- Network priority
Security Considerations
- Key Storage: Use secure enclaves or HSMs
- Rotation: Plan for key rotation
- Recovery: Implement social recovery
- Deactivation: Deactivate compromised DIDs immediately
Best Practices
- Use
did:keyfor development and testing - Use
did:luxfor production with stake - Include ZAP agent service endpoint in documents
- Register multiple verification methods
- Use ML-DSA-65 for post-quantum security
Last updated on