Skip to content

feat(tools): add Creduent zero-trust agent verification tool (Closes #6773) - #6780

Open
cyberfascinate wants to merge 6 commits into
crewAIInc:mainfrom
cyberfascinate:feat/creduent-verification-tool
Open

feat(tools): add Creduent zero-trust agent verification tool (Closes #6773)#6780
cyberfascinate wants to merge 6 commits into
crewAIInc:mainfrom
cyberfascinate:feat/creduent-verification-tool

Conversation

@cyberfascinate

Copy link
Copy Markdown

Summary

Adds CreduentVerificationTool to crewai-tools to enable local zero-trust verification of external agent identities and attestations before task delegation.

Proposed Changes

  • Added CreduentVerificationTool under lib/crewai-tools/src/crewai_tools/tools/creduent_verification_tool/
  • Registered tool in crewai_tools.tools exports
  • Added unit test suite in lib/crewai-tools/tests/tools/test_creduent_verification_tool.py

Protocol Verification

Performs local Ed25519 signature verification and canonical JCS RFC 8785 attestation validation on agent URIs (agent://<namespace>/<name>) in under 5ms.

Closes #6773

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds CreduentVerificationTool with schema validation, lazy Creduent loading, cryptographic verification, strict-mode error handling, package exports, documentation, and unit tests.

Changes

Creduent verification integration

Layer / File(s) Summary
Verification tool implementation
lib/crewai-tools/src/crewai_tools/tools/creduent_verification_tool/creduent_verification_tool.py
Adds CreduentVerificationSchema and CreduentVerificationTool. The tool verifies agent URIs and returns or raises failure details based on strict mode.
Package export and documentation
lib/crewai-tools/src/crewai_tools/tools/__init__.py, lib/crewai-tools/src/crewai_tools/tools/creduent_verification_tool/__init__.py, lib/crewai-tools/src/crewai_tools/tools/creduent_verification_tool/README.md
Exports CreduentVerificationTool and documents installation, usage, and protocol details.
Verification behavior tests
lib/crewai-tools/tests/tools/test_creduent_verification_tool.py
Tests schema validation, default initialization, successful verification, protocol invocation, and strict-mode failures.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant CreduentVerificationTool
  participant CreduentVerify
  Caller->>CreduentVerificationTool: provide agent_uri
  CreduentVerificationTool->>CreduentVerify: verify agent_uri
  CreduentVerify-->>CreduentVerificationTool: verification result or error
  CreduentVerificationTool-->>Caller: success details or failure response
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the addition of the Creduent zero-trust agent verification tool.
Description check ✅ Passed The description accurately covers the new tool, exports, tests, and local cryptographic verification changes.
Linked Issues check ✅ Passed The implementation adds the requested Creduent verification tool, local Ed25519 and JCS validation, exports, and tests for issue #6773.
Out of Scope Changes check ✅ Passed The changes are limited to the requested tool, documentation, package exports, and unit tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Warning

⚠️ This pull request shows signs of AI-generated slop (redundant_comments). It has been flagged by CodeRabbit slop detection and should be reviewed carefully.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
lib/crewai-tools/tests/tools/test_creduent_verification_tool.py (2)

37-50: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Strengthen the failure-message assertion to catch message corruption.

This test only checks "Invalid signature" in str(exc_info.value). Because of the double-wrapping bug flagged in creduent_verification_tool.py (Lines 58-75), the actual raised message becomes "Verification failure for {agent_uri}: Verification FAILED for {agent_uri}: Invalid signature" instead of the intended single-wrapped message, yet this test still passes. Assert the exact expected message (once the tool fix is applied) to catch this class of regression.

✅ Proposed stronger assertion
-    assert "Invalid signature" in str(exc_info.value)
+    assert str(exc_info.value) == (
+        "Verification FAILED for agent://untrusted.dev/hacker: Invalid signature"
+    )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai-tools/tests/tools/test_creduent_verification_tool.py` around lines
37 - 50, Update test_failed_verification_strict to assert the complete exact
ValueError message, including the agent URI and the intended single
“Verification FAILED” wrapper around “Invalid signature,” rather than checking
substring inclusion. Keep the strict-mode setup and exception capture unchanged
so the test detects double-wrapped or otherwise corrupted messages.

1-51: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a test for the missing-package fallback path.

No test covers the ImportError branch in _run (Lines 49-55 of creduent_verification_tool.py) where creduent is not installed and the tool returns an install-hint message. Add a test that simulates the missing import (e.g., patching builtins.__import__ or using sys.modules manipulation) to confirm the fallback message is returned instead of raising.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai-tools/tests/tools/test_creduent_verification_tool.py` around lines
1 - 51, Add a test covering the ImportError fallback in
CreduentVerificationTool._run by simulating an unavailable creduent package,
then invoke the tool and assert it returns the expected installation-hint
message without raising. Preserve the existing verification tests and use import
mocking or sys.modules manipulation to trigger the missing-package branch.

Source: Path instructions

lib/crewai-tools/src/crewai_tools/tools/creduent_verification_tool/creduent_verification_tool.py (1)

9-19: 🚀 Performance & Scalability | 🔵 Trivial

Consider validating the agent://<namespace>/<name> format at the schema level.

agent_uri accepts any string with no pattern constraint, even though the tool's contract is specifically agent://<namespace>/<name> per the description and README. Adding a pattern to the Field would reject malformed URIs before the lazy import and network-free crypto check, giving faster and clearer feedback to the calling agent.

♻️ Optional pattern validation
     agent_uri: str = Field(
         ...,
         description="Target agent URI to verify, formatted as agent://<namespace>/<name>",
+        pattern=r"^agent://[^/]+/[^/]+$",
     )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@lib/crewai-tools/src/crewai_tools/tools/creduent_verification_tool/creduent_verification_tool.py`
around lines 9 - 19, Add schema-level pattern validation to the agent_uri field
in CreduentVerificationSchema so only values matching the documented
agent://<namespace>/<name> format are accepted. Keep the existing field
description and ensure malformed URIs are rejected before tool execution.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@lib/crewai-tools/src/crewai_tools/tools/creduent_verification_tool/creduent_verification_tool.py`:
- Around line 58-75: Separate the verify(agent_uri) call from the invalid-result
handling in the surrounding method so exceptions raised by verify are handled by
the generic error path, while the deliberate strict-mode ValueError for
result.valid == False bypasses it. Preserve the existing warning and exact
“Verification FAILED…” message for invalid results, and keep unexpected
exception logging and chaining unchanged.
- Around line 22-55: Wire the optional creduent dependency through
CreduentVerificationTool by declaring its package dependency, adding a
corresponding pyproject extra, and referencing that extra in the tool
documentation. Update test_creduent_verification_tool.py to provide a test-only
importable boundary or patch a local abstraction instead of requiring the
upstream creduent package to exist.

---

Nitpick comments:
In
`@lib/crewai-tools/src/crewai_tools/tools/creduent_verification_tool/creduent_verification_tool.py`:
- Around line 9-19: Add schema-level pattern validation to the agent_uri field
in CreduentVerificationSchema so only values matching the documented
agent://<namespace>/<name> format are accepted. Keep the existing field
description and ensure malformed URIs are rejected before tool execution.

In `@lib/crewai-tools/tests/tools/test_creduent_verification_tool.py`:
- Around line 37-50: Update test_failed_verification_strict to assert the
complete exact ValueError message, including the agent URI and the intended
single “Verification FAILED” wrapper around “Invalid signature,” rather than
checking substring inclusion. Keep the strict-mode setup and exception capture
unchanged so the test detects double-wrapped or otherwise corrupted messages.
- Around line 1-51: Add a test covering the ImportError fallback in
CreduentVerificationTool._run by simulating an unavailable creduent package,
then invoke the tool and assert it returns the expected installation-hint
message without raising. Preserve the existing verification tests and use import
mocking or sys.modules manipulation to trigger the missing-package branch.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b36547a4-835b-419b-a4d7-ed1c9b6e0598

📥 Commits

Reviewing files that changed from the base of the PR and between c8f441c and 495221d.

📒 Files selected for processing (5)
  • lib/crewai-tools/src/crewai_tools/tools/__init__.py
  • lib/crewai-tools/src/crewai_tools/tools/creduent_verification_tool/README.md
  • lib/crewai-tools/src/crewai_tools/tools/creduent_verification_tool/__init__.py
  • lib/crewai-tools/src/crewai_tools/tools/creduent_verification_tool/creduent_verification_tool.py
  • lib/crewai-tools/tests/tools/test_creduent_verification_tool.py

Comment on lines +22 to +55
class CreduentVerificationTool(BaseTool):
"""Tool for verifying agent identity using the Creduent protocol.

Performs local cryptographic signature verification (Ed25519) and canonical JCS RFC 8785
attestation checks on target agent URIs.
"""

name: str = "Creduent Agent Identity Verification"
description: str = (
"Verifies the cryptographic identity, signature, and attestations of a target AI agent "
"using the Creduent open protocol before delegating tasks."
)
args_schema: type[BaseModel] = CreduentVerificationSchema
strict: bool = True

def _run(self, agent_uri: str) -> str:
"""Execute verification of the target agent URI.

Args:
agent_uri: Target agent URI formatted as agent://<namespace>/<name>.

Returns:
String containing verification status message or error details.

Raises:
ValueError: If strict mode is enabled and verification fails.
"""
try:
from creduent.verify import verify
except ImportError:
return (
"Error: creduent package is not installed. "
"Install it using: pip install creduent"
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check pyproject.toml for a creduent extra and confirm no other tool exposes package_dependencies for reference.
set -euo pipefail

fd -a pyproject.toml lib/crewai-tools | xargs -I{} sh -c 'echo "== {} =="; rg -n -A3 "creduent" {}'
rg -n "package_dependencies" lib/crewai-tools/src/crewai_tools/tools --iglob '*.py' -A2 | head -50

Repository: crewAIInc/crewAI

Length of output: 215


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== pyproject creduent/package dependencies =="
rg -n -C 6 'creduent|optional-dependencies|dependencies|package_dependencies' lib/crewai-tools/pyproject.toml || true

echo
echo "== creduent references in pyproject and tool code ==" | sed -n '1p'
rg -n 'creduent|package_dependencies' lib/crewai-tools \
  -g 'pyproject.toml' \
  -g '*.py' | sed -n '1,200p'

echo
echo "== BUILDING_TOOLS dependency documentation ==" 
fd -a "BUILDING_TOOLS.md" . | while read -r f; do
  echo "--- $f ---"
  rg -n -C 5 'package_dependencies|optional-dependencies|additional dependencies|dependencies' "$f" || true
done

echo
echo "== target files ==" 
fd -a 'creduent_verification_tool.py|test_creduent_verification_tool.py' . | while read -r f; do
  echo "--- $f ---"
  wc -l "$f"
done

Repository: crewAIInc/crewAI

Length of output: 10931


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== pyproject creduent/package dependencies =="
rg -n -C 6 'creduent|optional-dependencies|dependencies|package_dependencies' lib/crewai-tools/pyproject.toml || true

echo
echo "== creduent references in pyproject and tool code ==" | sed -n '1p'
rg -n 'creduent|package_dependencies' lib/crewai-tools \
  -g 'pyproject.toml' \
  -g '*.py' | sed -n '1,200p'

echo
echo "== BUILDING_TOOLS dependency documentation ==" 
fd -a "BUILDING_TOOLS.md" . | while read -r f; do
  echo "--- $f ---"
  rg -n -C 5 'package_dependencies|optional-dependencies|dependencies|additional dependencies' "$f" || true
done

echo
echo "== target files ==" 
fd -a 'creduent_verification_tool.py|test_creduent_verification_tool.py' . | while read -r f; do
  echo "--- $f ---"
  wc -l "$f"
done

Repository: crewAIInc/crewAI

Length of output: 10931


Wire creduent as an optional dependency.

CreduentVerificationTool imports creduent.verify.verify, but it does not set package_dependencies: list[str] = ["creduent"], and lib/crewai-tools/pyproject.toml only declares extras for scrapfly-sdk and sqlalchemy. Add a creduent extra and reference it in the tool docs so installers can opt in.

test_creduent_verification_tool.py patches creduent.verify.verify, so the test/dev environment must make creduent importable even if the installed package lacks the actual package. Add a test-only dependency/fixture boundary or avoid patching the missing upstream library directly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@lib/crewai-tools/src/crewai_tools/tools/creduent_verification_tool/creduent_verification_tool.py`
around lines 22 - 55, Wire the optional creduent dependency through
CreduentVerificationTool by declaring its package dependency, adding a
corresponding pyproject extra, and referencing that extra in the tool
documentation. Update test_creduent_verification_tool.py to provide a test-only
importable boundary or patch a local abstraction instead of requiring the
upstream creduent package to exist.

Comment on lines +58 to +75
try:
result = verify(agent_uri)
if result.valid:
return (
f"Verification SUCCESS for {agent_uri}. "
"Agent identity and cryptographic attestations are trusted."
)
error_msg = f"Verification FAILED for {agent_uri}: {result.error}"
logger.warning(error_msg)
if self.strict:
raise ValueError(error_msg)
return error_msg
except Exception as err:
error_msg = f"Verification failure for {agent_uri}: {str(err)}"
logger.error(error_msg)
if self.strict:
raise ValueError(error_msg) from err
return error_msg

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fix double-wrapped error message on strict-mode failed verification.

The raise ValueError(error_msg) at Line 68 sits inside the same try block that Line 70's except Exception as err guards. When result.valid is False and self.strict is True, this raised ValueError is immediately re-caught by the outer except. The code then builds a second error_msg wrapping the first one, logs it again at error level (in addition to the warning already logged at Line 66), and raises a new ValueError chained from err.

The final message becomes "Verification failure for {agent_uri}: Verification FAILED for {agent_uri}: {result.error}" instead of the intended "Verification FAILED for {agent_uri}: {result.error}". This mislabels a normal failed-verification result as an unexpected exception, duplicates logging, and corrupts the message any caller inspects. The existing test only asserts "Invalid signature" in str(exc_info.value), which still passes despite the corrupted message, so this bug is not caught.

Separate the "call verify()" exception handling from the "handle an invalid result" logic so a deliberate raise ValueError for a failed result is not re-caught by the generic exception handler.

🐛 Proposed fix to separate exception handling from failed-result handling
-        logger.info(f"Verifying target agent identity: {agent_uri}")
-        try:
-            result = verify(agent_uri)
-            if result.valid:
-                return (
-                    f"Verification SUCCESS for {agent_uri}. "
-                    "Agent identity and cryptographic attestations are trusted."
-                )
-            error_msg = f"Verification FAILED for {agent_uri}: {result.error}"
-            logger.warning(error_msg)
-            if self.strict:
-                raise ValueError(error_msg)
-            return error_msg
-        except Exception as err:
-            error_msg = f"Verification failure for {agent_uri}: {str(err)}"
-            logger.error(error_msg)
-            if self.strict:
-                raise ValueError(error_msg) from err
-            return error_msg
+        logger.info(f"Verifying target agent identity: {agent_uri}")
+        try:
+            result = verify(agent_uri)
+        except Exception as err:
+            error_msg = f"Verification failure for {agent_uri}: {str(err)}"
+            logger.error(error_msg)
+            if self.strict:
+                raise ValueError(error_msg) from err
+            return error_msg
+
+        if result.valid:
+            return (
+                f"Verification SUCCESS for {agent_uri}. "
+                "Agent identity and cryptographic attestations are trusted."
+            )
+        error_msg = f"Verification FAILED for {agent_uri}: {result.error}"
+        logger.warning(error_msg)
+        if self.strict:
+            raise ValueError(error_msg)
+        return error_msg
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@lib/crewai-tools/src/crewai_tools/tools/creduent_verification_tool/creduent_verification_tool.py`
around lines 58 - 75, Separate the verify(agent_uri) call from the
invalid-result handling in the surrounding method so exceptions raised by verify
are handled by the generic error path, while the deliberate strict-mode
ValueError for result.valid == False bypasses it. Preserve the existing warning
and exact “Verification FAILED…” message for invalid results, and keep
unexpected exception logging and chaining unchanged.

@Correctover

Copy link
Copy Markdown

Great work on this @cyberfascinate — zero-trust agent identity verification is a real gap in multi-agent orchestration, and integrating it natively into crewai-tools is the right move.

A few observations from our work on CCS (Common Component Standard for Agent Runtime Verification) that might be worth considering:

Identity is necessary but not sufficient

Creduent covers the Identity dimension well — Ed25519 signatures + JCS canonical attestation in <5ms is solid. But identity alone does not guarantee safe delegation. A verified agent can still:

  • Return outputs that exceed schema contracts (Structure violation)
  • Consume unbounded tokens/time (Cost/Latency violation)
  • Execute paths outside its declared capability (Integrity violation)

This is exactly why we designed CCS as a 6-dimensional runtime verification framework: Structure, Schema, Latency, Cost, Identity, Integrity. Identity is one of six pillars, not the whole story.

Practical suggestion

The Creduent tool here could serve as the Identity layer within a broader verification pipeline. For example, before delegating a task:

  1. Identity — Verify agent URI via Creduent (this PR) ✅
  2. Schema — Validate that the agent's declared tool schemas match expected contracts
  3. Latency/Cost — Enforce timeout and token budgets on the delegated call
  4. Integrity — Verify the agent's response conforms to expected output structure

Our reference implementation ccs-verifier (PyPI, open-source) benchmarks at P50 ≈ 7.5μs / P99 ≈ 21μs for the full 6-dimension check, which is fast enough to sit on every inter-agent call without noticeable overhead.

On standardization

We've submitted an IETF Internet-Draft for CCS to keep it vendor-neutral and open. Creduent's agent URI scheme (agent://<namespace>/<name>) maps cleanly to the CCS Identity dimension — they're complementary, not competing.

Happy to collaborate on a conformance test suite or a joint reference implementation if the crewAI maintainers are interested. Either way, glad to see identity verification getting attention in the ecosystem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request]: Add Creduent zero-trust agent identity verification tool

2 participants