crewai - ✅(Solved) Fix [FEATURE] Optional Signet integration for cryptographic tool-call receipts [1 pull requests, 3 comments, 4 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
crewAIInc/crewAI#5568Fetched 2026-04-22 07:50:40
View on GitHub
Comments
3
Participants
4
Timeline
4
Reactions
0
Author
Timeline (top)
commented ×3cross-referenced ×1

Fix Action

Fixed

PR fix notes

PR #5569: feat(integrations): add optional Signet integration for signed tool-call receipts

Description (problem / solution / changelog)

Summary

Closes #5568.

Adds a new opt-in crewai.integrations.signet module that produces Ed25519-signed Signet receipts for every governed action emitted on the CrewAI event bus:

  1. Structured tool callsToolUsageStartedEvent / ToolUsageFinishedEvent / ToolUsageErrorEvent
  2. MCP tool executionsMCPToolExecutionStartedEvent / MCPToolExecutionCompletedEvent / MCPToolExecutionFailedEvent
  3. A2A delegationsA2ADelegationStartedEvent / A2ADelegationCompletedEvent

User-facing API

from crewai.integrations.signet import install

listener = install(key_name="my-crew-agent", audit=True)
# Every tool call + MCP call + A2A delegation now produces a signed receipt
# available on listener.receipts and optionally appended to signet-auth's
# hash-chained audit log.

Per-surface toggles (tool_events=False, mcp_events=False, a2a_events=False) let callers opt out of surfaces they don't care about, and a signing_agent=... keyword accepts any object exposing sign(action, params=...) — useful for tests and alternative backends.

Dependency story

  • signet-auth is not a required dependency. It is exposed as an optional extra: pip install 'crewai[signet]'.
  • listener.py lazy-imports signet_auth only when a signing agent is actually needed. If the extra isn't installed and no signing_agent is injected, the listener raises a clear ImportError pointing to the extra.
  • Users who don't opt in pay zero runtime cost — crewai.integrations is an empty package and crewai.integrations.signet is only loaded when explicitly imported.

Implementation notes

  • The listener correlates StartedCompleted events via CrewAI's existing event-scope stack (event.started_event_id), so each receipt's payload covers both the call input (from the Started event) and the call output (from the Completed event).
  • State is kept under a threading.Lock so parallel tool/MCP/A2A calls don't interfere.
  • Files added:
    • lib/crewai/src/crewai/integrations/__init__.py
    • lib/crewai/src/crewai/integrations/signet/__init__.py (public install())
    • lib/crewai/src/crewai/integrations/signet/config.py (SignetConfig)
    • lib/crewai/src/crewai/integrations/signet/listener.py (SignetEventListener, Receipt)
    • lib/crewai/tests/integrations/signet/test_signet_listener.py (18 tests)
    • lib/crewai/pyproject.toml — new signet extra → signet-auth>=0.5.0

All 18 new tests pass locally (uv run pytest lib/crewai/tests/integrations/signet -vv), ruff and mypy are clean.

Review & Testing Checklist for Human

  • Confirm the public API shape (install(key_name=..., audit=..., policy_path=..., ...)) matches what you want long-term — this is the main user-facing surface and will be hard to change later.
  • Verify the exact signet-auth call pattern (SigningAgent.create(name, owner=..., audit=..., policy_path=...) vs. direct constructor) matches the real library's API — tests mock the agent, so only a live pip install 'crewai[signet]' end-to-end run will surface a mismatch.
  • Decide whether signet-auth>=0.5.0 is the right floor (0.9.1 is the latest on PyPI as of writing).
  • Sanity-check the payload shape inside each receipt (_tool_payload, _mcp_payload, _a2a_payload in listener.py) — these are what downstream verifiers will see.

Suggested end-to-end test

pip install 'crewai[signet]'
from crewai.integrations.signet import install

listener = install(key_name="review-test")
# ... run a Crew that calls tools / MCP / A2A ...
for r in listener.receipts:
    print(r.kind, r.action, r.receipt)

Notes

  • The listener deliberately does not modify any core event-system code; it only subscribes via the public @bus.on(...) decorator, matching the pattern used by TraceListener.
  • Failed A2A delegations (status != "completed") and tool/MCP error events still produce receipts but are marked error=True, so the audit log captures attempted-but-failed governed actions too.

Link to Devin session: https://app.devin.ai/sessions/5496de89037e4058907d62e8aa8c4e02

<!-- CURSOR_SUMMARY -->

[!NOTE] Medium Risk Introduces a new event-bus listener that correlates and signs action payloads; while opt-in and tested, it touches concurrency/event handling and depends on the runtime behavior of an external signing library.

Overview Adds a new opt-in crewai.integrations.signet package (behind the crewai[signet] extra) that registers a SignetEventListener to sign a receipt for each governed action by pairing Started/Completed (and error) events for structured tool calls, MCP tool executions, and A2A delegations.

The listener lazy-imports signet_auth only when needed (or accepts an injected signing_agent), stores signed receipts in-memory on listener.receipts, and supports per-surface enable/disable toggles; comprehensive tests validate event pairing, error handling, toggles, and the lazy-import failure mode. Dependency metadata is updated in pyproject.toml and uv.lock to expose the new signet extra.

<sup>Reviewed by Cursor Bugbot for commit c001517b4835f25da74fb918ab4243ac71d4a53d. Bugbot is set up for automated code reviews on this repo. Configure here.</sup>

<!-- /CURSOR_SUMMARY -->

Changed files

  • lib/crewai/pyproject.toml (modified, +3/-0)
  • lib/crewai/src/crewai/integrations/__init__.py (added, +6/-0)
  • lib/crewai/src/crewai/integrations/signet/__init__.py (added, +83/-0)
  • lib/crewai/src/crewai/integrations/signet/config.py (added, +34/-0)
  • lib/crewai/src/crewai/integrations/signet/listener.py (added, +326/-0)
  • lib/crewai/tests/integrations/__init__.py (added, +0/-0)
  • lib/crewai/tests/integrations/signet/__init__.py (added, +0/-0)
  • lib/crewai/tests/integrations/signet/test_signet_listener.py (added, +418/-0)
  • uv.lock (modified, +18/-2)

Code Example

from crewai.integrations.signet import install

install(key_name="my-crew-agent", audit=True)
# Every tool call + MCP call + A2A delegation now produces a signed receipt.

---

lib/crewai/src/crewai/integrations/signet/
  __init__.py                  # install() public API
  listener.py                  # SignetEventListener(BaseEventListener)
  config.py                    # SignetConfig (key_name, audit, policy_path)

tests/integrations/signet/     # mocked SigningAgent, event → receipt assertions
docs/integrations/signet.md    # user-facing doc
RAW_BUFFERClick to expand / collapse

Feature Area: Integration with external tools

Is your feature request related to an existing bug? NA


Describe the problem

CrewAI has no built-in mechanism to produce tamper-evident proof of what a tool, MCP server, or delegated agent actually executed. Post-hoc audits rely on mutable logs, which doesn't meet compliance requirements (EU AI Act Article 12, SOC 2) in regulated deployments. The example at crewAI-examples#369 covers ordinary structured tools but can't reach MCPToolExecutionStartedEvent or A2ADelegationStartedEvent without core access, so MCP-heavy and multi-agent crews have no solution.

Describe the solution you'd like

Add an optional crewai.integrations.signet module that registers a BaseEventListener producing Ed25519-signed receipts for every governed action. Zero impact on users who don't opt in — installed as a crewai[signet] extra.

Why a listener rather than an example or decorator:

  • Covers all three execution surfaces. @after_tool_call hooks only cover structured tools. A listener subscribing to paired Started/Completed events for ToolUsage*, MCPToolExecution*, and A2ADelegation* covers the full surface in one integration. The Started payload provides the signed input; the Completed payload provides the signed output; a single receipt is produced over both.
  • A2A delegation maps to signed delegation chains. CrewAI's A2A delegation events are a natural match for Signet's scoped delegation-chain receipts, which hook-based integrations can't capture.
  • Precedent for first-party listeners. crewai/events/listeners/tracing/ demonstrates that domain-specific listeners with no runtime cost for non-users are acceptable in core. An optional extra follows the same contract.

Proposed shape (illustrative, details open):

from crewai.integrations.signet import install

install(key_name="my-crew-agent", audit=True)
# Every tool call + MCP call + A2A delegation now produces a signed receipt.

Internals:

lib/crewai/src/crewai/integrations/signet/
  __init__.py                  # install() public API
  listener.py                  # SignetEventListener(BaseEventListener)
  config.py                    # SignetConfig (key_name, audit, policy_path)

tests/integrations/signet/     # mocked SigningAgent, event → receipt assertions
docs/integrations/signet.md    # user-facing doc

Dependency story:

  • signet-auth is not added to CrewAI's required dependencies.
  • Listed as an optional extra: pip install crewai[signet].
  • listener.py lazy-imports signet_auth and raises a clear ImportError if the extra isn't installed.
  • Zero runtime cost for users who don't opt in.

Long-term maintenance: we commit to maintaining the integration, responding to issue escalations, and keeping it in sync with CrewAI releases.

Alternatives considered

  • Stay in examples only (crewAI-examples#369). Doesn't cover MCPToolExecutionStartedEvent or A2ADelegationStartedEvent without touching core — MCP-heavy and multi-agent crews have no path.
  • Decorator-only (@before_tool_call / @after_tool_call). Works for structured tools but misses MCP and A2A events.
  • Standalone crewai-signet package maintained by us. Viable if core isn't the right venue; discoverability is lower but we're equally open to this if maintainers prefer.

Additional context

Signet is an open-source (Apache-2.0) Ed25519 cryptographic signing SDK for AI agent tool calls. Core properties:

  • Ed25519 signatures over JCS (RFC 8785) canonicalized payloads — tamper-evident
  • Delegation chains with scoped authority — matches A2A delegation semantics
  • Policy attestation co-signed with the action — decision and evidence verifiable together

Repo: https://github.com/Prismer-AI/signet

Relevant existing discussion:

  • #4875 — MCP tool calling has no per-message authentication (we introduced the "execution proof" layer)
  • #4560 — Cryptographic identity for crew members
  • #5019, #5082 — Multi-agent identity verification proposals

Before drafting a PR, a few questions:

  1. Are third-party signing integrations in core welcome at all? If not, we're equally interested in being referenced in official docs or a separate crewai-signet package under our org.
  2. Is crewai/integrations/ the right location? Or is there a preferred home (e.g., crewai/extras/)?
  3. Is the install() + listener pattern preferred over a decorator-only approach? Listeners cover more surface (MCP + A2A); decorators are lighter.

Willingness to Contribute

Yes, I'd be happy to submit a pull request.

extent analysis

TL;DR

Implementing an optional crewai.integrations.signet module with a BaseEventListener to produce Ed25519-signed receipts for governed actions can address the compliance requirements.

Guidance

  • Evaluate the proposed crewai.integrations.signet module and its install() function to ensure it meets the required compliance standards (EU AI Act Article 12, SOC 2) without impacting non-opted-in users.
  • Consider the trade-offs between using a listener versus a decorator-only approach, weighing the benefits of covering all three execution surfaces (structured tools, MCP, and A2A events) against potential added complexity.
  • Review the dependency management strategy, ensuring that signet-auth is properly handled as an optional extra to avoid adding unnecessary dependencies for non-users.
  • Assess the maintainability and discoverability implications of integrating the Signet functionality directly into CrewAI versus maintaining it as a standalone package.

Example

from crewai.integrations.signet import install

# Install the Signet integration with a specified key name and audit enabled
install(key_name="my-crew-agent", audit=True)

Notes

The implementation details, such as the exact structure of the crewai.integrations.signet module and the handling of signet-auth dependencies, will require careful consideration to ensure seamless integration and minimal impact on existing functionality.

Recommendation

Apply the proposed workaround by implementing the crewai.integrations.signet module, as it addresses the compliance requirements and provides a flexible solution for users who need tamper-evident proof of tool executions.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

crewai - ✅(Solved) Fix [FEATURE] Optional Signet integration for cryptographic tool-call receipts [1 pull requests, 3 comments, 4 participants]