Skip to main content

Zero-dependency-bloat Python library for W3C Decentralized Identifiers (DIDs) using Ed25519 keys

Project description

didlite 🆔

Beta Python License

⚠️ BETA STATUS - SECURITY AUDIT PENDING

This library is in active development and has not undergone an independent security audit. While we've conducted comprehensive internal security hardening with 23+ security fixes, we recommend against production use until an external audit is complete.

Use at your own risk. See SECURITY.md for vulnerability reporting.


Verifiable Identity for Agents, IoT, and Edge Devices.

didlite is a zero-dependency-bloat Python library that generates W3C Standard Decentralized Identifiers (DIDs) using Ed25519 keys.

It allows any Python program (Drone, Sensor, AI Agent) to create a cryptographically verifiable identity and sign data without needing a central server, certificate authority, or blockchain.


⚡ Why didlite?

Most Identity libraries (SSI) are massive. They require Rust compilers, system binaries, or heavy async runtimes.

  • Zero Bloat: Pure Python wrapper around pynacl (libsodium).
  • Standards Compliant: Produces valid did:key identifiers (W3C CCG).
  • Web-Ready: Signs standard JSON Web Signatures (JWS).
  • ARM64 Native: Runs seamlessly on Raspberry Pi, AWS Graviton, and M1/M2/M3 Macs.

The Problem it Solves

Scenario 1: AI Agents - You deploy autonomous agents that need to communicate and transact with each other.

  • The Old Way: Central API keys (shared secrets = single point of failure) or OAuth servers (requires infrastructure).
  • The didlite Way: Each agent generates its own identity. Messages are cryptographically signed. Trust is mathematical, not infrastructural.

Scenario 2: IoT at Scale - You have 1,000 temperature sensors deployed in the field.

  • The Old Way: Hardcode a shared API key (insecure) or manage 1,000 mTLS certificates (painful).
  • The didlite Way: Each sensor generates its own ID at startup. The server verifies the signature mathematically. No database required.

How It Works: Trust Architecture

sequenceDiagram
    participant Agent as AI Agent / IoT Device
    participant Verifier as Server / Gateway

    Note over Agent: Generate Identity
    Agent->>Agent: identity = AgentIdentity()
    Agent->>Agent: did = "did:key:z6Mkh..."

    Note over Agent: Sign Message
    Agent->>Agent: token = create_jws(identity, payload)

    Agent->>Verifier: Send signed token

    Note over Verifier: Verify Signature
    Verifier->>Verifier: header, payload = verify_jws(token)
    Verifier->>Verifier: Extract DID from header['kid']
    Verifier->>Verifier: Resolve DID → public key
    Verifier->>Verifier: Verify signature with public key

    alt Signature Valid
        Verifier->>Agent: ✅ Trust established
        Note over Verifier: No database lookup needed<br/>DID IS the public key
    else Signature Invalid
        Verifier->>Agent: ❌ Reject (tampering detected)
    end

Key Insight: The DID itself encodes the public key (via Multicodec + Multibase). No PKI infrastructure, no certificate authorities, no centralized identity servers.

Performance Benchmarks (v0.2.3) - 2025-12-30

Environment: Raspberry Pi 5 8GB

Operation Avg Time Throughput Notes
Identity Generation 0.11ms ~9,200/sec No overhead from v0.2.3 changes
Token Creation 0.08ms ~13,100/sec Includes iat timestamp validation
Token Verification 0.24ms ~4,200/sec Now returns (header, payload) tuple
DID Extraction 0.01ms ~190,000/sec NEW - Fast header parsing without signature verification
Custom Headers 0.08ms ~13,000/sec NEW - Zero overhead for custom typ, etc.

Key Takeaways:

  • ✅ v0.2.3 header enhancements add negligible overhead (<0.01ms)
  • extract_signer_did() is ~24x faster than full verification (useful for routing/logging)
  • ✅ All operations remain suitable for high-throughput IoT/edge deployments
  • ✅ Ed25519 + PyNaCl's libsodium wrapper delivers excellent ARM64 performance

📦 Installation

pip install didlite

Note: didlite is currently in beta (v0.2.3). Breaking changes may occur before v1.0.0.


🚀 Quick Start

Example 1: AI Agent Communication

Agent 1 (Research Agent) - Collects and signs lead data:

import didlite

# Agent generates its own identity
research_agent = didlite.AgentIdentity()
print(f"Research Agent DID: {research_agent.did}")

# Create a signed lead record
lead_data = {
    "action": "lead_discovered",
    "company": "Acme Corp",
    "industry": "manufacturing",
    "interest": "IoT sensors",
    "source": "web_research"
}

# Sign the lead data
signed_lead = didlite.create_jws(research_agent, lead_data)
# Now send signed_lead to CRM agent...

Agent 2 (CRM Agent) - Verifies and processes:

import didlite

# Receive signed lead from research agent
# signed_lead = "eyJhbGciOiJFZERTQ..."

try:
    # Verify the signature
    header, payload = didlite.verify_jws(signed_lead)

    # Extract the signer's DID
    signer_did = header['kid']

    print(f"✅ Verified lead from: {signer_did}")
    print(f"Company: {payload['company']}")
    print(f"Interest: {payload['interest']}")

    # Add to CRM database with attribution to research_agent...

except Exception as e:
    print(f"❌ Invalid signature - rejecting lead: {e}")

Example 2: IoT Sensor Data

The Sensor - Generates identity and signs telemetry:

import didlite

# In production, load seed from secure storage
sensor = didlite.AgentIdentity()

# Sign telemetry data
telemetry = {
    "temp": 24.5,
    "unit": "C",
    "timestamp": 1678900000
}

token = didlite.create_jws(sensor, telemetry)
# Send token to gateway...

The Gateway - Verifies without database lookup:

import didlite

# token = "eyJhbGciOiJFZERTQ..." # Received from sensor

try:
    header, payload = didlite.verify_jws(token)

    print(f"Valid data from: {header['kid']}")
    print(f"Temperature: {payload['temp']}°{payload['unit']}")

except Exception as e:
    print(f"SECURITY ALERT: Invalid signature! {e}")

🛠 Advanced Usage

Persistent Identity (Using Seeds)

If a device reboots, you want it to have the same DID. Use a secure 32-byte seed (e.g., from an environment variable or HSM).

import os
from didlite import AgentIdentity

# Load secret from secure storage
seed_bytes = os.getenv("DEVICE_SECRET_KEY").encode()[:32]

agent = AgentIdentity(seed=seed_bytes)

Resolving DIDs

If you just want to check a DID string and get the raw public key bytes:

from didlite import resolve_did_to_key

did = "did:key:z6MkhaXgBZDvotDkL5257..."
verify_key = resolve_did_to_key(did)

# Now use verify_key to check raw signatures

🧪 Testing & Quality

Test Coverage (v0.2.4)

Coverage by Module:

Module Coverage Status
didlite/__init__.py 100% ✅ Complete coverage
didlite/core.py 96% ✅ All security-critical paths tested
didlite/jws.py 99% ✅ Algorithm confusion attacks prevented
didlite/keystore.py 93% ✅ All storage backends validated
Overall 95.7% ✅ Production-ready (351 statements, 336 covered)

Test Suite Breakdown:

Test Category Tests Description
Compliance (test_compliance.py) 18 W3C DID & RFC 7515/7519 JWT/JWS standards
Core (test_core.py) 37 Identity, DID resolution, JWK/PEM export
Fuzzing (test_fuzzing.py) 32 Malformed inputs, attack scenarios, DoS prevention
Integration (test_integration.py) 5 Cross-library compatibility (authlib)
JWS (test_jws.py) 63 Token creation/verification, headers, expiration
Keystore (test_keystore.py) 49 Storage backends, encryption, persistence
Security (test_security.py) 32 Error sanitization, input validation
Total 236 233 passed, 3 skipped

What's Tested:

  • ✅ W3C DID:key compliance (RFC 8032, Multicodec 0xed01, base58btc encoding)
  • ✅ JWS/JWT standards (RFC 7515, RFC 7519, EdDSA signatures)
  • ✅ Attack prevention (algorithm confusion, signature tampering, token replay, missing 'kid')
  • ✅ Keystore security (PBKDF2 encryption, file permissions 0o600, path traversal)
  • ✅ Cross-library compatibility (authlib JWS/JWK interop)
  • ✅ Edge cases (malformed tokens, corrupted data, expired tokens, future-dated tokens)

Run tests: pytest --cov=didlite --cov-report=term-missing See docs/TESTING_GUIDE.md for detailed testing documentation.


🤝 Contributing

We keep this library "lite" on purpose. We only support did:key to ensure maximum portability for Edge AI and IoT.

📄 License

Apache 2.0 - Commercial use allowed.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

didlite-0.2.4.tar.gz (108.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

didlite-0.2.4-py3-none-any.whl (22.1 kB view details)

Uploaded Python 3

File details

Details for the file didlite-0.2.4.tar.gz.

File metadata

  • Download URL: didlite-0.2.4.tar.gz
  • Upload date:
  • Size: 108.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for didlite-0.2.4.tar.gz
Algorithm Hash digest
SHA256 407b788b371e9a1c05433dfde5657cfbdd25af58f32c6e90242c4c5a10536f7f
MD5 f3fb293120d051ba89fa00ab645f4a5f
BLAKE2b-256 274bf0a99ba6c6e7aa23222176c6755d4924ab9f7047887fe7827cb1f5f32f27

See more details on using hashes here.

Provenance

The following attestation bundles were made for didlite-0.2.4.tar.gz:

Publisher: publish.yml on jondepalma/didlite-pkg

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file didlite-0.2.4-py3-none-any.whl.

File metadata

  • Download URL: didlite-0.2.4-py3-none-any.whl
  • Upload date:
  • Size: 22.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for didlite-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 f9330eb28846437e9aba1d58eba3a7ee5470763cb08fb3c071e3b342367ce78a
MD5 4c71c59b5f130c3a2ab8aba27e736346
BLAKE2b-256 14d7965aa459dba0f3d5925879ccda4b2a6cb4aace61026133d1b563917fbccb

See more details on using hashes here.

Provenance

The following attestation bundles were made for didlite-0.2.4-py3-none-any.whl:

Publisher: publish.yml on jondepalma/didlite-pkg

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page