CrewAI
In multi-agent crews, per-agent identity is the whole point: each member gets its own keys, its own hash chain, and its own trust score — so when something goes wrong you know which agent did it.
One client per crew member
import os
from proofledger import create_client
from crewai import Agent, Task, Crew
def audited(agent_name: str, role: str):
"""A ProofLedger client bound to one crew member's identity."""
client = create_client(
api_key=os.environ["PROOFLEDGER_API_KEY"],
agent_name=agent_name,
owner="growth-team",
framework="crewai",
model="gpt-4.1",
)
client.register_agent(name=role)
return client
researcher_pl = audited("crew-researcher", "Market Researcher")
writer_pl = audited("crew-writer", "Report Writer")
WF = "wf_market_report_001"
researcher = Agent(
role="Market Researcher", goal="Find pricing data", backstory="…",
step_callback=lambda step: researcher_pl.log_decision(
workflow_id=WF, action=f"Step: {str(step)[:180]}"),
)
writer = Agent(role="Report Writer", goal="Write the report", backstory="…")
# Log the handoff between agents explicitly:
researcher_pl.log_workflow_step(WF, event_type="task_received",
action="Research competitor pricing")
crew = Crew(agents=[researcher, writer], tasks=[research_task, write_task])
result = crew.kickoff()
researcher_pl.log_workflow_step(WF, action="Handed findings to writer")
writer_pl.log_workflow_step(WF, status="completed",
action="Report delivered")Note
create_client gives each member an isolated client (its own identity and signing key) while sharing one API key. Both agents appear separately in the registry with their own timelines — and the shared workflow_id stitches the crew's work into one replayable story.