Skip to content

VeritasActa/deerflow-receipts

Repository files navigation

DeerFlow Receipt Signing

Ed25519-signed, independently verifiable receipts for DeerFlow's memory, MCP config, and tool calls.

Three self-contained Python modules that add cryptographic integrity to DeerFlow's control plane. Each produces receipts conforming to IETF Internet-Draft draft-farley-acta-signed-receipts-01.

Why receipts? Authentication prevents unauthorized access. Receipt signing prevents undetected tampering — even by authorized parties. These address the integrity gaps exposed in DeerFlow #1646 (MCP config disclosure) and #1648 (memory disclosure).

Quick Start

# Clone and enter
cd examples/deerflow-receipts

# Install signing (optional — works unsigned without it)
pip install pynacl

# Run the end-to-end demo
python demo.py

# Verify receipts offline
python verify.py example_receipts.jsonl --verbose

RFC acceptance artifacts

Following the DeerFlow discussion feedback, the repo now treats cryptographic integrity as separate evidence objects rather than one generic receipt feature.

  • schemas/memory-receipt.schema.json - memory item content and metadata integrity
  • schemas/mcp-config-receipt.schema.json - authorized MCP config state and revocation
  • schemas/delegation-receipt.schema.json - parent/user authorization for sub-agent work
  • schemas/subagent-completion-receipt.schema.json - sub-agent output bound to a delegation
  • NEGATIVE-TEST-MATRIX.md - adversarial acceptance criteria for the RFC
  • tests/negative_cases.py - runnable stdlib-only harness for the five negative cases

Run the negative acceptance tests:

python tests/negative_cases.py

The tests cover replay after revocation, metadata-only memory tampering, middle-chain deletion, cross-run receipt reuse, and signing-key rotation with historical verification.

Modules

1. Memory Integrity (memory_integrity.py)

Signs DeerFlow's memory.json writes with hash-chain receipts. Each receipt includes:

  • SHA-256 hash of the memory state (content + file)
  • Hash chain link to previous state
  • Fact count and metadata
  • Ed25519 signature
from memory_integrity import MemoryIntegrity, SigningConfig

mi = MemoryIntegrity(
    memory_path=".deer-flow/memory.json",
    output_path="memory_receipts.jsonl",
    signing_config=SigningConfig(
        private_key_hex="...",
        public_key_hex="...",
        kid="deerflow-prod-01",
        issuer="deerflow-memory-integrity",
    ),
)

# Sign current state (call after each memory update)
receipt = mi.sign_current_state()

# Verify current state hasn't been tampered with
result = mi.verify_current_state()
assert result["status"] == "verified"

# Watch mode: continuously sign memory changes
# python memory_integrity.py watch

Use case: Prove a memory entry hasn't been modified since it was written. An admin or auditor can verify the hash chain offline to detect any tampering — even by the server operator.


2. MCP Config Signer (mcp_config_signer.py)

Signs MCP configuration changes with receipts that record which servers were enabled/disabled and who authorized the change.

from mcp_config_signer import MCPConfigSigner, add_mcp_signing_middleware

# Standalone
signer = MCPConfigSigner(config_path="extensions_config.json")
receipt = signer.sign_current_config(
    authorization_context="admin_cli",
    change_source="User enabled brave-search via settings",
)

# As FastAPI middleware (wraps DeerFlow's Gateway API)
from fastapi import FastAPI
app = FastAPI()
add_mcp_signing_middleware(app, signer)
# Now every PUT to /api/mcp/config produces a signed receipt

Each receipt includes:

  • Config hash (SHA-256)
  • Which MCP servers are enabled/disabled
  • Authorization context (who/what approved this config)
  • Ed25519 signature

Use case: Prove the MCP configuration was authorized. When an auditor asks "was this MCP server enabled by an admin or by a compromised sub-agent?", the receipt chain provides the answer.


3. Receipt Middleware (receipt_middleware.py)

LangGraph/LangChain callback handler that signs tool calls and sub-agent completions.

from receipt_middleware import ReceiptMiddleware, SigningConfig

middleware = ReceiptMiddleware(
    output_path="receipts.jsonl",
    policy={"bash": "deny"},  # Block shell access
    agent_id="deerflow-lead-agent",
    signing_config=SigningConfig(...),
)

# Use with any LangGraph/LangChain agent
agent = create_react_agent(llm, tools, callbacks=[middleware])
result = agent.invoke({"input": "..."})

# Every tool call now has a signed receipt
print(middleware.get_stats())

Receipt types:

  • deerflow:tool_call — tool invocations (allow, deny, error)
  • deerflow:subagent_completion — sub-agent attestation

Features:

  • Receipt chaining via parent_receipt_id (Section 4.3 of IETF draft)
  • Policy enforcement at on_tool_start boundary
  • Input/output hashing (not raw content — privacy preserving)
  • Duration tracking
  • Graceful degradation without langchain-core

Use case: Prove which sub-agent produced which output, and that no tool call was added or removed from the record after the fact.


4. Standalone Verifier (verify.py)

Zero-dependency verifier for receipt files.

# Structural + hash chain verification (no PyNaCl needed)
python verify.py receipts.jsonl

# Full Ed25519 signature verification
pip install pynacl
python verify.py receipts.jsonl --verbose

# Also works with the npm verifier
npx @veritasacta/verify receipts.jsonl

5. Verify Receipt MCP Tool (verify_mcp_tool.py)

Exposes receipt verification as an MCP tool so any agent in a DeerFlow workflow can verify another agent's receipts before trusting its output.

# Run as a standalone MCP server (stdio)
python verify_mcp_tool.py

Configure in your MCP client (DeerFlow, Claude Desktop, etc.):

{
  "mcpServers": {
    "deerflow-verify": {
      "command": "python",
      "args": ["verify_mcp_tool.py"],
      "type": "stdio"
    }
  }
}

Or register with an existing MCP server:

from mcp.server import Server
from verify_mcp_tool import register_verify_tools

server = Server("my-server")
register_verify_tools(server)

Three tools are exposed:

  • verify_receipt - Verify a single receipt's integrity and signature
  • verify_chain - Verify an ordered array of receipts for hash continuity
  • verify_receipt_file - Verify all receipts in a JSONL file on disk

This closes the cross-agent trust loop: agent A calls verify_receipt to validate agent B's output receipt before accepting it as input.


Integration with DeerFlow

Minimal: Watch memory.json

# Start DeerFlow normally, then in a separate terminal:
python memory_integrity.py watch

This monitors .deer-flow/memory.json and signs every change. No changes to DeerFlow code required.

Moderate: FastAPI middleware

Add to DeerFlow's Gateway API startup:

# In backend gateway startup
from mcp_config_signer import MCPConfigSigner, add_mcp_signing_middleware

signer = MCPConfigSigner()
add_mcp_signing_middleware(app, signer)

Full: LangGraph callback

Add to DeerFlow's agent config:

# In agent initialization
from receipt_middleware import ReceiptMiddleware

middleware = ReceiptMiddleware(agent_id="deerflow-lead-agent")
# Add to LangGraph callbacks

Receipt Format

All receipts conform to IETF Internet-Draft draft-farley-acta-signed-receipts-01:

{
  "type": "deerflow:memory_write",
  "receipt_id": "a1b2c3d4e5f6",
  "content_hash": "sha256:abc123...",
  "previous_hash": "sha256:def456...",
  "timestamp": 1712789400.0,
  "facts_count": 42,
  "spec": "draft-farley-acta-signed-receipts-01",
  "issuer_certification": "self-signed",
  "signature": "ed25519:...",
  "public_key": "ed25519:..."
}

Dependencies

Dependency Required? Purpose
Python 3.12+ Runtime
PyNaCl Optional Ed25519 signing + verification
langchain-core Optional LangGraph callback integration
starlette Optional FastAPI middleware integration
mcp Optional MCP server SDK for verify tool

Without PyNaCl, receipts are emitted unsigned (structural integrity + hash chains only). Without langchain-core, the middleware module still exports classes but uses stub base classes. Without the mcp package, verify_mcp_tool.py falls back to a manual JSON-RPC stdio server.

Related

License

MIT

About

Ed25519-signed receipts for DeerFlow memory, MCP config, and tool calls. IETF draft-farley-acta-signed-receipts. Includes verify_receipt MCP tool.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages