Skip to main content

Action-time proof and delegation verification for MCP agents

Project description

AgentLedger

CI PyPI version Python versions License: Apache 2.0

Your agent executed a tool. AgentLedger records — tamper-evidently — which action ran, on whose authority, and whether it stayed within the delegation it was given.

pip install agentledger-llm

What this is and isn't. AgentLedger is an audit layer, not an enforcement layer. By default a tool call that violates its receipt is recorded as a proof and still runs — it is not blocked. Hash-chaining makes the log tamper-evident; it does not prove an action was authorized at execution time by a cryptographically verified identity. See Security note.


The problem

OAuth tells you who authenticated. It doesn't tell you which specific action was authorized, by whom, through what delegation, with what record.

AgentLedger fills that gap — it records the delegation intent and an attributable, tamper-evident proof of each tool call against it.


20-second quickstart

import asyncio
from agentledger import Ledger

ledger = Ledger()

receipt = ledger.issue_receipt(
    principal="user:daniel",
    agent="agent:financial-assistant",
    permitted_tools=["get_exchange_rates"],
    permitted_scopes=["read:rates"],
    expires_in=3600,
)

@ledger.record(receipt=receipt)
async def get_exchange_rates(params, context=None):
    return {"base": "USD", "GBP": 0.79, "EUR": 0.92}

async def main():
    await get_exchange_rates({"base": "USD"})
    ledger.report()
    ledger.verify(ledger.last().proof_id).print()

asyncio.run(main())

Want violations to block instead of just record? Opt in:

@ledger.record(receipt=receipt, on_violation="raise")  # "record" (default) | "warn" | "raise"
async def delete_alert(params, context=None):
    ...

Cryptographic delegation (v2)

v1 records that an action matched a receipt. v2 adds cryptographic proof that the grant was real — the principal signs the receipt (Ed25519), and the verifier checks it against a trusted key. A within_delegation = True verdict on a signed receipt means the named agent acted under a grant the principal actually signed — not just that the strings matched.

pip install "agentledger-llm[crypto]"
from agentledger import Ledger, InMemoryKeyProvider
from agentledger.signing import generate_keypair

# Principal holds the private key and signs the grant
priv, pub = generate_keypair()
receipt = ledger.issue_receipt(principal="user:d", agent="agent:a",
                               permitted_tools=["get_rates"],
                               permitted_scopes=["read:rates"])
receipt.sign(priv)

# Verifier trusts only public keys it already holds (never one in the receipt)
ledger = Ledger(key_provider=InMemoryKeyProvider({"user:d": pub}))

@ledger.record(receipt=receipt, require_signed=True, scopes=["read:rates"])
async def get_rates(params, context=None):
    return {"GBP": 0.79}
  • Default is graceful: unsigned (v1-style) receipts still work — recorded with signature_verified=None, never reported as verified. require_signed=True makes unsigned/unverifiable a violation.
  • Scopes: scopes=[...] checks each against the receipt's permitted_scopes.
  • Agent identity (optional): pass an IdentityProvider (e.g. SpiffeIdentityProvider) to bind the workload to the receipt's agent; without one, the verdict records identity_status="unverified".

What v2 does and does not defend against is enumerated in docs/threat-model.md; the design is in docs/v2-design.md.


The three-layer model

AgentLedger sits after authentication, not instead of it:

Layer Standard What it does
Authentication OAuth 2.1 Who are you?
Workload identity WIMSE WPT + SPIFFE/SPIRE Which agent are you?
Action proof AgentLedger What did you do, recorded against whom?

What it records

For every tool call:

  • Which tool was called, by which agent, for which principal
  • Whether the call was within the delegation receipt
  • Any scope violations — each with an explanation and a remediation
  • A hash-chained, tamper-evident proof record
  • Latency and error state

What it does NOT do

AgentLedger v1 explicitly does not:

  • Replace OAuth or any identity provider
  • Enforce authorization by default (it records; opt in with on_violation="raise")
  • Provide mid-chain revocation (v3 — see roadmap)
  • Handle multi-hop delegation chains (v3)
  • Provide enterprise compliance (SOC 2, legal)
  • Compete with Prefactor (enterprise) or KYA-OS (DID-based)

As of v2, signed receipts + a pluggable identity provider do add cryptographic delegation proof and agent-identity binding — within the limits set out in docs/threat-model.md (a compromised signing key, a malicious principal, and an in-process verifier remain out of scope).

See docs/roadmap.md for v2/v3 scope and entry criteria.


vs alternatives

Tool Open source pip install Action record WIMSE-aligned Developer-first
AgentLedger
Prefactor ❌ (enterprise)
KYA-OS ⚠️ (DID-heavy)
FinMCP inline N/A ✅ (one server)

CLI

Command What it does Exit code
agentledger init Scaffold agentledger.yaml + working agent_example.py 0
agentledger report [--log PATH] [--format terminal|html] Summarize the proof log 0 always (informational)
agentledger verify <proof_id> [--log PATH] Verdict for one proof 1 if violations recorded
agentledger chain [--log PATH] Verify hash-chain integrity 1 if tampered

TraceForge integration

If agentrace-llm is installed, AgentLedger automatically attaches proof metadata (agentledger.proof_id, agentledger.tool, agentledger.within_delegation, …) to the active TraceForge span. If it isn't installed, enrichment is a silent no-op (a one-time warning makes the no-op discoverable). Zero configuration required.

pip install "agentledger-llm[traceforge]"

Security note

Hash-chain integrity proves the proof log has not been tampered with after recording — and only while the log is read-only or externally anchored; an attacker with write access to the log can rewrite the whole chain. It does not prove actions were authorized at execution time by a cryptographically verified agent identity. Input/output digests are tamper-evidence, not confidentiality — low-entropy inputs can be recovered by guessing, so treat proof logs as sensitive. For cryptographic identity binding you need SPIFFE/SPIRE + AgentLedger v2. See docs/wimse-alignment.md.


Changelog

See CHANGELOG.md for release history.


Built by

Daniel Blanco · danblanco.dev · hello@danblanco.dev · Apache-2.0

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

agentledger_llm-0.2.0.tar.gz (32.5 kB view details)

Uploaded Source

Built Distribution

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

agentledger_llm-0.2.0-py3-none-any.whl (30.0 kB view details)

Uploaded Python 3

File details

Details for the file agentledger_llm-0.2.0.tar.gz.

File metadata

  • Download URL: agentledger_llm-0.2.0.tar.gz
  • Upload date:
  • Size: 32.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for agentledger_llm-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b7d402b247ffa31283786c6c3d9727b67341300fd68c8033bcbc6d41d0f54ce7
MD5 31d70c62ec9ead2cc47bfe22f4399060
BLAKE2b-256 488a909787fd28f60063f22f5764a9f7d27fb20c483105b86f770ac1094c2132

See more details on using hashes here.

Provenance

The following attestation bundles were made for agentledger_llm-0.2.0.tar.gz:

Publisher: release.yml on Danultimate/Agent-Ledger

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

File details

Details for the file agentledger_llm-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for agentledger_llm-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4103c9104667a412bf2d088cf227f3d1bff5729c4fcc55a06738bf414409863c
MD5 746b26bc9d7d898b2875cd3c5cfcd980
BLAKE2b-256 7e36f62dda9132240b39376dc9f2181cd878d3513cf5eb1670898fa4ee48a22c

See more details on using hashes here.

Provenance

The following attestation bundles were made for agentledger_llm-0.2.0-py3-none-any.whl:

Publisher: release.yml on Danultimate/Agent-Ledger

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