Skip to main content

Tamper-evident execution ledger for AI agents. Log every tool call, decision, and error to a cryptographically verifiable audit trail.

Project description

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

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

Register agent identity on-chain for transparent AI governance:

# Register an agent profile
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

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

aegis_ledger_sdk-0.3.3.tar.gz (113.1 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.3.3-py3-none-any.whl (132.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for aegis_ledger_sdk-0.3.3.tar.gz
Algorithm Hash digest
SHA256 f8c6e009b3ae1deb3b30d96c498f7d38a187f9f171d190e4db9103cf1783feec
MD5 e74c439a2499b821620c938924a41968
BLAKE2b-256 714ed180b94220dd28a592d6d85898071607045ac2e1c7014788077e4924810f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for aegis_ledger_sdk-0.3.3-py3-none-any.whl
Algorithm Hash digest
SHA256 484ce0848c10ff159b0ea82d06ccd81dd5dbbff939af918ce0aafaef0b6e2d2d
MD5 6b167673fe5dd56c8aea8c037bf37f41
BLAKE2b-256 7f902b7d84fd554b8982335f6e2f3008b08976f6c78d8be556c91a5e652c4d99

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