Spaces:
Running
Running
File size: 7,409 Bytes
7d7a6cb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | """Example demonstrating the FastMCP Provenance Ledger functionality."""
import asyncio
from datetime import datetime
from fastmcp import FastMCP
from fastmcp.ledger import ProvenanceLedger, LedgerEvent, EventType
def create_ledger_server():
"""Create a FastMCP server with ledger functionality."""
server = FastMCP("LedgerExampleServer")
# Enable the provenance ledger
ledger = server.enable_ledger(database_url="sqlite:///example_ledger.db")
@server.tool
def log_tool_call(tool_name: str, parameters: dict, result: str) -> str:
"""Log a tool call to the provenance ledger."""
# Create a ledger event
event = LedgerEvent(
event_type=EventType.TOOL_CALL,
actor_id="system",
resource_id=f"tool://{tool_name}",
action="execute",
metadata={
"tool_name": tool_name,
"parameters": parameters,
"result": result,
"timestamp": datetime.utcnow().isoformat()
}
)
# Append to ledger
entry = ledger.append_event(event)
return f"Logged tool call {tool_name} as entry {entry.sequence_number}"
@server.tool
def log_policy_decision(policy_name: str, decision: str, context: dict) -> str:
"""Log a policy decision to the provenance ledger."""
event = LedgerEvent(
event_type=EventType.POLICY_DECISION,
actor_id="policy_engine",
resource_id=f"policy://{policy_name}",
action="evaluate",
metadata={
"policy_name": policy_name,
"decision": decision,
"context": context,
"timestamp": datetime.utcnow().isoformat()
}
)
entry = ledger.append_event(event)
return f"Logged policy decision {policy_name} as entry {entry.sequence_number}"
@server.tool
def log_data_flow(source: str, destination: str, data_type: str, size: int) -> str:
"""Log a data flow event to the provenance ledger."""
event = LedgerEvent(
event_type=EventType.DATA_FLOW,
actor_id="data_processor",
resource_id=f"data://{source}",
action="transfer",
metadata={
"source": source,
"destination": destination,
"data_type": data_type,
"size_bytes": size,
"timestamp": datetime.utcnow().isoformat()
}
)
entry = ledger.append_event(event)
return f"Logged data flow from {source} to {destination} as entry {entry.sequence_number}"
@server.tool
def verify_ledger_integrity() -> dict:
"""Verify the integrity of the entire ledger."""
# Verify chain integrity
chain_valid = ledger.verify_chain_integrity()
# Get statistics
stats = ledger.get_ledger_statistics()
return {
"chain_integrity": chain_valid,
"statistics": stats,
"verification_timestamp": datetime.utcnow().isoformat()
}
@server.tool
def get_ledger_entry(sequence_number: int) -> dict:
"""Get a specific ledger entry."""
entry = ledger.get_entry(sequence_number)
if not entry:
return {"error": f"Entry {sequence_number} not found"}
event = entry.get_event()
return {
"sequence_number": entry.sequence_number,
"entry_hash": entry.entry_hash,
"previous_hash": entry.previous_hash,
"created_at": entry.created_at.isoformat(),
"event": {
"type": event.event_type,
"actor_id": event.actor_id,
"action": event.action,
"metadata": event.metadata
}
}
return server, ledger
async def demonstrate_ledger_functionality():
"""Demonstrate the ledger functionality."""
print("๐ Creating FastMCP server with Provenance Ledger...")
server, ledger = create_ledger_server()
print("\n๐ Logging various events to the ledger...")
# Log some tool calls
print(server._tool_manager.call_tool("log_tool_call", {
"tool_name": "file_reader",
"parameters": {"path": "/data/file.txt"},
"result": "success"
}))
print(server._tool_manager.call_tool("log_tool_call", {
"tool_name": "data_processor",
"parameters": {"input": "raw_data", "format": "json"},
"result": "processed_data"
}))
# Log policy decisions
print(server._tool_manager.call_tool("log_policy_decision", {
"policy_name": "access_control",
"decision": "allow",
"context": {"user": "alice", "resource": "sensitive_data"}
}))
print(server._tool_manager.call_tool("log_policy_decision", {
"policy_name": "data_retention",
"decision": "delete",
"context": {"age_days": 365, "type": "logs"}
}))
# Log data flows
print(server._tool_manager.call_tool("log_data_flow", {
"source": "database",
"destination": "cache",
"data_type": "user_profiles",
"size": 1024
}))
print(server._tool_manager.call_tool("log_data_flow", {
"source": "api",
"destination": "analytics",
"data_type": "usage_metrics",
"size": 512
}))
print("\n๐ Verifying ledger integrity...")
integrity_result = server._tool_manager.call_tool("verify_ledger_integrity", {})
print(f"Chain integrity: {integrity_result['chain_integrity']}")
print(f"Total entries: {integrity_result['statistics']['total_entries']}")
print(f"Total blocks: {integrity_result['statistics']['total_blocks']}")
print("\n๐ Retrieving specific entries...")
for i in range(1, 4):
entry = server._tool_manager.call_tool("get_ledger_entry", {"sequence_number": i})
if "error" not in entry:
print(f"Entry {i}: {entry['event']['type']} - {entry['event']['action']}")
print("\n๐ Demonstrating hash chaining...")
entry1 = ledger.get_entry(1)
entry2 = ledger.get_entry(2)
if entry1 and entry2:
print(f"Entry 1 hash: {entry1.entry_hash[:16]}...")
print(f"Entry 2 previous hash: {entry2.previous_hash[:16]}...")
print(f"Hash chain intact: {entry2.previous_hash == entry1.entry_hash}")
print("\n๐ณ Demonstrating Merkle tree verification...")
# Get the first block
block = ledger.get_block(1)
if block:
print(f"Block 1 Merkle root: {block.merkle_root[:16]}...")
print(f"Block 1 entry count: {block.entry_count}")
# Verify block integrity
block_valid = ledger.verify_block_integrity(1)
print(f"Block 1 integrity: {block_valid}")
print("\nโ
Ledger demonstration complete!")
print("\nThe ledger provides:")
print("- Tamper-evident hash chaining between entries")
print("- Merkle tree verification for blocks")
print("- Cryptographic integrity guarantees")
print("- Audit trail for all system events")
print("- HTTP API endpoints for external access")
if __name__ == "__main__":
asyncio.run(demonstrate_ledger_functionality())
|