Skip to main content

Aegis Ledger SDK

Tamper-evident audit logs for AI agents.

When autonomous agents take actions, their logs become verifiable audit evidence. Aegis hash-chains every tool call, signs it with Ed25519 or post-quantum signatures (ML-DSA-65, ML-DSA-87, SLH-DSA-128s, Hybrid), and stores it on the Internet Computer — where tampering is cryptographically detectable. Not by you, not your ops team, not the hosting provider — any modification breaks the hash chain.

PyPI Python Downloads License: MIT

pip install aegis-ledger-sdk

For MCP server support: pip install aegis-ledger-sdk[mcp] For post-quantum signatures: pip install aegis-ledger-sdk[pq] For everything: pip install aegis-ledger-sdk[all]

The Problem

Your AI agent just autonomously called a payment API, transferred $47,000, and the client says it wasn't authorized. Your logs are in CloudWatch. The client's lawyer asks: "Can you prove these logs haven't been edited since the incident?"

You can't. Aegis fixes this.

Quickstart

from aegis import AegisClient

# After: pip install aegis-ledger-sdk && aegis init
client = AegisClient.from_config()

@client.trace()
def call_stripe(amount: int, currency: str) -> dict:
    return stripe.PaymentIntent.create(amount=amount, currency=currency)

# Every call is now tamper-evident logged:
#   SHA-256(input) + SHA-256(output) + signature (Ed25519/PQ) + hash-chain link

Verify any entry — no authentication required:

aegis verify toqqq-lqaaa-aaaae-afc2a-cai act_a7f3b2c19e4d
# VERIFIED — chain hash valid, signature valid

Explicit Logging API

# Tool/API calls
client.log_tool_call("stripe.charge", input_data={"amount": 5000}, output_data={"id": "ch_xxx"}, duration_ms=340)

# Decisions with reasoning
client.log_decision("Selected cheapest shipping provider", confidence=0.92, input_data=options)

# Observations (sensor data, API responses)
client.log_observation(input_data=sensor_reading, output_data=parsed_result)

# Errors
client.log_error("payment.process", input_data=request, error=exc, duration_ms=120)

# Human overrides (EU AI Act Art. 14 compliance)
client.log_human_override("Manager approved exception", input_data=original, output_data=override)

# Batch import
client.log_batch([
    {"tool": "search", "input_data": "query", "output_data": "results"},
    {"tool": "summarize", "input_data": "results", "output_data": "summary"},
])

Span Grouping

Group related actions under a parent for structured traces:

with client.span("process_order", reasoning="Customer checkout flow") as span_id:
    client.log_tool_call("inventory.check", ...)
    client.log_tool_call("payment.charge", ...)
    # Both calls have parent_action_id = span_id

Session Management

# Start a new session (resets sequence counter)
new_id = client.new_session()

# Use as context manager for automatic cleanup
with AegisClient(...) as client:
    client.log_tool_call(...)
# Spill buffer drained on exit

KYA — Know Your Agent (Roadmap)

Note: register_agent() and update_agent_profile() are currently available via CanisterOps only. A convenience wrapper on the main AegisClient is planned.

Register agent identity on-chain for transparent AI governance:

# Register an agent profile (via CanisterOps)
client.register_agent(
    agent_id="agent-billing-v2",
    name="Billing Agent",
    description="Handles invoice generation and payment processing",
    capabilities=["stripe.charge", "invoice.create", "refund.process"],
    framework="langchain",
    model_id="gpt-4o",
)

# Update an existing profile
client.update_agent_profile("agent-billing-v2", name="Billing Agent v3", model_id="gpt-4.1")

# Retrieve public agent facts (no auth required)
facts = client.get_agent_facts("agent-billing-v2")

Agent profiles are stored on-chain and publicly verifiable — any third party can inspect what an agent claims to do.

OpenTelemetry Correlation

Aegis entries can carry OpenTelemetry context for correlation with your existing observability stack:

# Auto-extracted from active OTel span (if opentelemetry SDK installed)
client.log_tool_call("search", input_data=q, output_data=r, duration_ms=50)
# → otel_trace_id, otel_span_id auto-populated

# Or pass explicitly
client.log_tool_call(
    "search", input_data=q, output_data=r, duration_ms=50,
    otel_trace_id="abc123", otel_span_id="def456",
    cost_usd=0.003, token_count=1500,
)

Framework Integrations

LangChain

from aegis.langchain import AegisCallbackHandler

handler = AegisCallbackHandler(client)
agent.invoke({"input": "Process refund"}, config={"callbacks": [handler]})

CrewAI

from aegis.crewai import AegisCrewCallback

callback = AegisCrewCallback(client)
crew = Crew(agents=[...], tasks=[...], step_callback=callback)

OpenAI Agents SDK

from aegis.openai_agents import AegisAgentTracer

tracer = AegisAgentTracer(client)
with tracer.trace() as tid:
    result = await Runner.run(agent, "Process this request")

AutoGen / AG2

from aegis.autogen import AegisAutoGenHook

hook = AegisAutoGenHook(client)
hook.on_tool_call("search", arguments={"q": "test"}, caller="assistant")
hook.on_tool_result("search", result="found 5 items", caller="assistant")

Anthropic Agent SDK

from aegis.anthropic_sdk import AegisAnthropicTracer

tracer = AegisAnthropicTracer(client)
tracer.on_tool_use("search", tool_input={"q": "test"}, tool_response="5 results")
tracer.on_session_start("session_123")
tracer.on_subagent_start("sub_1", "researcher")

MCP (Model Context Protocol)

pip install aegis-ledger-sdk[mcp]
aegis-mcp  # starts MCP server (stdio transport)

Any MCP-compatible agent can log actions to the tamper-evident ledger via MCP tools.

Async & Batch Support

# Async functions work directly with @trace
@client.trace()
async def fetch_data(url: str) -> dict:
    async with aiohttp.ClientSession() as session:
        resp = await session.get(url)
        return await resp.json()

Post-Quantum Signatures

Five signature algorithms with crypto-agility:

Algorithm Type Key Size Use Case
Ed25519 Classical 32 B Default, fast
ML-DSA-65 Post-Quantum (FIPS 204) 1952 B PQ Level 3
ML-DSA-87 Post-Quantum (FIPS 204) 2592 B CNSA 2.0 Level 5
SLH-DSA-128s Hash-based (FIPS 205) 32 B Conservative PQ fallback
Hybrid Ed25519 + ML-DSA-65 1984 B Best of both worlds
# Generate PQ keys
# aegis keygen ./key.mldsa65 --algorithm ml-dsa-65
# aegis keygen ./key --algorithm hybrid

client = AegisClient(
    ...,
    signature_scheme="hybrid",
    signing_key_path="./key.mldsa65",
)

Configure via ~/.aegis/config.toml:

[signing]
default_scheme = "hybrid"
signing_key_path = "~/.aegis/keys/agent.mldsa65"

PII Protection

PII is automatically detected and redacted before transmission (enabled by default):

client = AegisClient(..., redact_pii=True)  # default

# Detected patterns: email, phone, IP, SSN, AHV (Swiss), credit cards
# PII is replaced with sha256:<128-bit hash> — verifiable but not reversible

CLI

# Setup & diagnostics
aegis init                                                 # Interactive setup wizard
aegis test                                                 # Send test entry + verify on-chain
aegis doctor                                               # Check SDK health (config, keys, canister)
aegis version                                              # Print SDK version

# Key generation
aegis keygen ./key.pem                                     # Generate Ed25519 keypair
aegis keygen ./key.mldsa65 --algorithm ml-dsa-65           # Generate ML-DSA-65 keypair
aegis keygen ./key --algorithm hybrid                      # Generate Hybrid keypair

# Verification
aegis verify <canister_id> <action_id>                     # Verify single entry
aegis verify-chain <canister_id> <session_id>              # Verify full session chain

# Canister queries
aegis status <canister_id>                                 # Canister health + chain stats
aegis list-sessions <canister_id>                          # List your sessions
aegis session-analytics <session_id>                       # Error rate, duration, action types
aegis org-stats <canister_id>                              # Aggregated org statistics
aegis spill-status                                         # Show pending offline buffer

# Compliance reports
aegis report <canister_id> --format eu-ai-act              # EU AI Act Art. 12
aegis report <canister_id> --format all -o ./reports/      # All formats

# Key management (self-service)
aegis register-key <id> --key-file <f>                     # Register new API key
aegis revoke <key_id>                                      # Revoke key (confirmation required)
aegis reactivate-key <key_id>                              # Reactivate revoked key
aegis delete-key <key_id>                                  # Permanently delete revoked key
aegis update-key-desc <key_id> <desc>                      # Update key description

# Migration
aegis migrate <canister_id> <session_id> --to hybrid       # Re-sign with new algorithm
aegis purge-session <session_id>                           # Purge session entries (owner/admin)

How It Works

Your Agent                    Aegis SDK                    ICP Canister
    |                             |                             |
    |-- call_stripe(500, "usd") ->|                             |
    |                             |-- SHA-256(input)            |
    |                             |-- SHA-256(output)           |
    |                             |-- sign (Ed25519/PQ) ------->|
    |                             |                    verify signature
    |                             |                    check sequence
    |                             |                    chain_hash = SHA-256(
    |                             |                      prev_hash + payload
    |                             |                    )
    |                             |                    store in append-only ledger
    |                             |<-- action_id ---------------|
    |<-- return result -----------|                             |

Fail-open: if canister unreachable, entries buffer locally (~/.aegis/spill/) and retry.

What Gets Logged

Field Description
input_hash SHA-256 of full input (raw data never stored on-chain)
output_hash SHA-256 of full output
tool Tool/API name
duration_ms Wall-clock execution time
chain_hash SHA-256 linking to previous entry
payload_signature Cryptographic signature (Ed25519, ML-DSA-65, ML-DSA-87, SLH-DSA-128s, or Hybrid)
sequence_number Monotonic counter (gap detection)
otel_trace_id OpenTelemetry trace ID (optional, for correlation)
otel_span_id OpenTelemetry span ID (optional)
cost_usd LLM call cost in USD (optional)
token_count Token usage (optional)

What does NOT get logged: Raw payloads, API keys, secrets, PII. Only hashes — you control your data.

Compliance

Generate verifiable compliance reports:

from aegis.report import generate_report, generate_pdf, ReportFormat

report = generate_report("toqqq-...", format=ReportFormat.EU_AI_ACT, stats=stats, health=health)
generate_pdf(report, "compliance-report.pdf")

Supported frameworks: EU AI Act Art. 12, ISO/IEC 42001, AIUC-1 (insurance underwriting).

Links

Normal logging = trust the system. Aegis = verify the record.

License

MIT

Download files

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

Source Distribution

aegis_ledger_sdk-0.4.1.tar.gz (127.8 kB view details)

Uploaded Source

Built Distribution

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

aegis_ledger_sdk-0.4.1-py3-none-any.whl (148.0 kB view details)

Uploaded Python 3

File details

Details for the file aegis_ledger_sdk-0.4.1.tar.gz.

File metadata

  • Download URL: aegis_ledger_sdk-0.4.1.tar.gz
  • Upload date:
  • Size: 127.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for aegis_ledger_sdk-0.4.1.tar.gz
Algorithm Hash digest
SHA256 8712591de979551ecf5d595846aa7f380c257bf80a7dd770bf1f79584a6cd637
MD5 88b44ce2fd6ec0f0872949df5fae8c75
BLAKE2b-256 3246069ac4ad06b03892287508cdccd99f59e0a70013ea376c009c51958a3e8b

See more details on using hashes here.

File details

Details for the file aegis_ledger_sdk-0.4.1-py3-none-any.whl.

File metadata

File hashes

Hashes for aegis_ledger_sdk-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b5be4a8220ba2c288046ea9d72f59f4a10f880f8f29e28c1ae3c9f59c096885b
MD5 535f9d81188f53e67575eb47d635462c
BLAKE2b-256 8e289183c3d8e2bdc1d41c12e092060a9dac3d23852f2df5686e88676a3dce76

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.4.1 This release

2 files

0.3.5

2 files

0.3.4

2 files

0.3.3

2 files

0.3.2

2 files

0.3.1

2 files

0.2.11

2 files

0.2.10

2 files

0.2.9

2 files

0.2.8

2 files

0.2.6

2 files

0.2.5

2 files

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.1.0

2 files

Supported by

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