Skip to main content

Python SDK for the Elydora tamper-evident audit platform

Project description

Elydora Python SDK

Official Python SDK for the Elydora tamper-evident audit platform. Build cryptographically verifiable audit trails for AI agent operations.

Installation

pip install elydora

Requires Python 3.9+.

Quick Start

from elydora import ElydoraClient

# Authenticate
auth = ElydoraClient.login("https://api.elydora.com", "user@example.com", "password")

# Create client
client = ElydoraClient(
    org_id=auth["user"]["org_id"],
    agent_id="my-agent-id",
    private_key="<base64url-encoded-ed25519-seed>",
    base_url="https://api.elydora.com",
    token=auth["token"],
)

# Create and submit an operation
eor = client.create_operation(
    operation_type="data.access",
    subject={"user_id": "u-123", "resource": "patient-record"},
    action={"type": "read", "scope": "full"},
    payload={"record_id": "rec-456"},
)
response = client.submit_operation(eor)
print("Receipt:", response["receipt"]["receipt_id"])

Async Support

from elydora import AsyncElydoraClient

async def main():
    client = AsyncElydoraClient(
        org_id="org-123",
        agent_id="agent-456",
        private_key="<base64url-encoded-ed25519-seed>",
        token="<jwt-token>",
    )

    eor = client.create_operation(
        operation_type="inference",
        subject={"model": "gpt-4"},
        action={"type": "completion"},
    )
    response = await client.submit_operation(eor)
    await client.close()

CLI

The SDK includes a CLI for installing audit hooks into AI coding agents.

elydora install \
  --agent claudecode \
  --org_id org-123 \
  --agent_id agent-456 \
  --private_key <key> \
  --kid agent-456-key-v1

Commands

Command Description
elydora install Install Elydora audit hook for a coding agent
elydora uninstall Remove Elydora audit hook for a coding agent
elydora status Show installation status for all agents
elydora agents List supported coding agents

Supported Agents

Agent Key
Claude Code claudecode
Copilot CLI copilot
Cursor cursor
Gemini CLI gemini
Kiro CLI kirocli
Kiro IDE kiroide
Letta Code letta
OpenCode opencode

API Reference

Configuration

client = ElydoraClient(
    org_id="org-123",           # Organization ID
    agent_id="agent-456",       # Agent ID
    private_key="<seed>",       # Base64url-encoded Ed25519 seed
    base_url="https://...",     # API base URL (default: https://api.elydora.com)
    ttl_ms=30000,               # Operation TTL in ms (default: 30000)
    max_retries=3,              # Max retries on transient failures (default: 3)
    token="<jwt>",              # Optional JWT bearer token
)

Authentication

# Register a new user and organization
reg = ElydoraClient.register(base_url, email, password, display_name=None, org_name=None)

# Login and receive a JWT
auth = ElydoraClient.login(base_url, email, password)

# Get current authenticated user profile
me = client.get_me()

# Issue a new API token (with optional TTL in seconds)
token_resp = client.issue_token(ttl_seconds=3600)

Operations

# Create a signed EOR locally (no network call)
eor = client.create_operation(
    operation_type="inference",
    subject={"model": "gpt-4"},
    action={"type": "completion"},
    payload={"prompt": "Hello"},
)

# Submit to API
response = client.submit_operation(eor)

# Retrieve an operation
op = client.get_operation(operation_id)

# Verify integrity
result = client.verify_operation(operation_id)

Agent Management

# Register a new agent
agent = client.register_agent({
    "agent_id": "my-agent",
    "display_name": "My Agent",
    "responsible_entity": "team@example.com",
    "keys": [{"kid": "key-v1", "public_key": "<base64url>", "algorithm": "ed25519"}],
})

# Get agent details
details = client.get_agent(agent_id)

# Freeze an agent
client.freeze_agent(agent_id, reason="security review")

# Revoke a key
client.revoke_key(agent_id, kid, reason="key rotation")

# List all agents in the organization
agents_resp = client.list_agents()

# Unfreeze a previously frozen agent
client.unfreeze_agent(agent_id, reason="review complete")

# Delete an agent permanently
deleted_resp = client.delete_agent(agent_id)

Audit

import time

results = client.query_audit(
    agent_id="agent-123",
    operation_type="inference",
    start_time=int(time.time() * 1000) - 86400000,
    end_time=int(time.time() * 1000),
    limit=50,
)

Epochs

epochs = client.list_epochs()
epoch = client.get_epoch(epoch_id)

Exports

export = client.create_export(
    start_time=start,
    end_time=end,
    format="json",
)

exports = client.list_exports()
detail = client.get_export(export_id)

# Download export file data
data = client.download_export(export_id)

JWKS

jwks = client.get_jwks()

Health

# Check API health (no authentication required)
health = client.health()
# health["status"], health["version"], health["protocol_version"], health["timestamp"]

Crypto Functions

The SDK exports low-level cryptographic primitives for advanced use:

from elydora import (
    jcs_canonicalize,          # RFC 8785 JSON Canonicalization
    sha256_base64url,          # SHA-256 hash as base64url
    compute_chain_hash,        # Chain hash computation
    compute_payload_hash,      # Payload hash (SHA-256 of JCS-canonicalized payload)
    sign_ed25519,              # Ed25519 signing
    sign_eor,                  # Sign an EOR dict
    get_public_key_base64url,  # Derive public key from private seed
)

Utility Functions

from elydora import (
    base64url_encode,   # Encode bytes to base64url (no padding)
    base64url_decode,   # Decode base64url string to bytes
    generate_nonce,     # Generate 16-byte random nonce (base64url)
    generate_uuidv7,    # Generate UUIDv7 (time-ordered, RFC 9562)
)

Type Definitions

All types are TypedDict classes for structural typing:

from elydora import (
    # Protocol types
    EOR,                       # Elydora Operation Record
    EAR,                       # Elydora Acknowledgment Receipt

    # Entity types
    Agent, AgentKey, Operation, Receipt, Epoch, Export, Organization, User,

    # API response types
    RegisterAgentResponse, GetAgentResponse, ListAgentsResponse,
    DeleteAgentResponse, SubmitOperationResponse, GetOperationResponse,
    VerifyOperationResponse, AuditQueryResponse, GetEpochResponse,
    ListEpochsResponse, CreateExportResponse, GetExportResponse,
    ListExportsResponse, JWKSResponse, AuthRegisterResponse,
    AuthLoginResponse, GetMeResponse, IssueTokenResponse, HealthResponse,

    # Request types
    RegisterAgentRequest,
)

Error Handling

from elydora import ElydoraError

try:
    client.submit_operation(eor)
except ElydoraError as e:
    print(e.code)        # e.g. "INVALID_SIGNATURE"
    print(e.message)     # Human-readable message
    print(e.status_code) # HTTP status code
    print(e.request_id)  # Request ID for support

Dependencies

License

MIT

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

elydora-1.1.0.tar.gz (30.6 kB view details)

Uploaded Source

Built Distribution

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

elydora-1.1.0-py3-none-any.whl (44.5 kB view details)

Uploaded Python 3

File details

Details for the file elydora-1.1.0.tar.gz.

File metadata

  • Download URL: elydora-1.1.0.tar.gz
  • Upload date:
  • Size: 30.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for elydora-1.1.0.tar.gz
Algorithm Hash digest
SHA256 01248882ea19fdaf45f03e32583f548f050e544f676242c99f50c6957668c4b6
MD5 b9159eca2a07ace8283947a972f849fd
BLAKE2b-256 9e37be7fba8548207be7e1768ddd0a816a5bcb67047be28450a70ef54350d277

See more details on using hashes here.

File details

Details for the file elydora-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: elydora-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 44.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for elydora-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f02c8588a905be1c87dc54c09b299449dffa708e30c7f962b1126182d58fc4d1
MD5 9e7ae6fa23a68fca0a75df684f949615
BLAKE2b-256 e772bb6a8f758b5ca7080b78b0b3f25bf09f11d659647cae1b89ed53d290bb39

See more details on using hashes here.

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