Skip to content

[Extension] AgentMesh Trust Layer - Cryptographic Identity for Dify Agents#32079

Closed
imran-siddique wants to merge 4 commits intolanggenius:mainfrom
imran-siddique:agentmesh-trust-extension
Closed

[Extension] AgentMesh Trust Layer - Cryptographic Identity for Dify Agents#32079
imran-siddique wants to merge 4 commits intolanggenius:mainfrom
imran-siddique:agentmesh-trust-extension

Conversation

@imran-siddique
Copy link
Copy Markdown

Adds a trust layer extension for Dify with cryptographic identity and trust verification.

Features:

  • Ed25519-based agent identities with DIDs
  • Peer verification and trust scoring (0.0-1.0)
  • Flask middleware with @trust_required decorator
  • Audit logging for compliance

HTTP Headers: X-Agent-DID, X-Agent-Public-Key, X-Agent-Capabilities

Backward compatible - trust is optional, no breaking changes.

See api/extensions/agentmesh/README.md for full documentation.

Adds cryptographic identity and trust verification for Dify agents/workflows:

## Features
- **CMVKIdentity**: Ed25519-based agent identities with DIDs
- **TrustManager**: Peer verification with caching and trust scoring
- **TrustMiddleware**: Flask middleware for API endpoint protection
- **Audit logging**: Track all trust decisions for compliance

## Usage
- Protect API endpoints with @trust_required decorator
- Verify workflow steps before execution
- Agent-to-agent trust verification via HTTP headers

## HTTP Headers
- X-Agent-DID: Agent's decentralized identifier
- X-Agent-Public-Key: Base64 Ed25519 public key
- X-Agent-Capabilities: Comma-separated capabilities

Fully backward compatible - trust is optional and won't break existing workflows.
Copilot AI review requested due to automatic review settings February 6, 2026 22:55
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. 💪 enhancement New feature or request labels Feb 6, 2026
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @imran-siddique, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new AgentMesh Trust Layer extension for Dify, significantly enhancing the security and reliability of agent interactions. It establishes a robust framework for cryptographic identity and trust verification, allowing Dify to authenticate agents, assess their trustworthiness through dynamic scoring, and enforce access based on defined trust levels and capabilities. This layer is seamlessly integrated via Flask middleware, providing a flexible and backward-compatible solution for securing agent-to-agent communication and workflow execution within the Dify ecosystem.

Highlights

  • Cryptographic Identity: Introduces Ed25519-based agent identities using Decentralized Identifiers (DIDs) for Dify agents, enabling secure and verifiable identification.
  • Trust Verification & Scoring: Implements a system for peer verification and dynamic trust scoring (0.0-1.0) based on behavioral history, allowing Dify to assess the trustworthiness of interacting agents.
  • Flask Integration: Provides a Flask middleware and a @trust_required decorator to easily protect API endpoints, automatically checking agent DIDs, public keys, and capabilities from HTTP headers.
  • Audit Logging: Adds comprehensive audit logging for all trust decisions, ensuring compliance and providing a traceable record of verification outcomes.
  • Backward Compatibility: The extension is designed to be optional and non-breaking, allowing existing Dify functionalities to operate without requiring trust verification unless explicitly configured.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • api/extensions/agentmesh/README.md
    • Added comprehensive documentation for the AgentMesh Trust Extension.
    • Details the overview, installation, and usage examples for protecting API endpoints, verifying workflow steps, and securing agent-to-agent communication.
    • Explains HTTP headers used, trust score calculation logic, audit logging features, and configuration options.
    • Includes links to related AgentMesh projects.
  • api/extensions/agentmesh/init.py
    • Added a new Python package initialization file for the agentmesh extension.
    • Exports core components: CMVKIdentity, CMVKSignature, TrustManager, TrustVerificationResult, and TrustMiddleware for easy access.
  • api/extensions/agentmesh/identity.py
    • Added CMVKIdentity dataclass for creating and managing cryptographic identities using Ed25519 keys and Decentralized Identifiers (DIDs).
    • Includes methods for generating new identities, signing data with a private key, and verifying signatures with a public key.
    • Defines CMVKSignature dataclass to represent cryptographic signatures.
    • Provides a fallback mechanism for cryptographic operations if the cryptography library is not available.
  • api/extensions/agentmesh/middleware.py
    • Added TrustMiddleware class, implemented as a singleton, for integrating trust verification into Flask applications.
    • Introduces the @trust_required decorator to protect API endpoints, automatically extracting agent DID, public key, and capabilities from X-Agent-DID, X-Agent-Public-Key, and X-Agent-Capabilities HTTP headers.
    • Handles trust verification and returns appropriate HTTP 403 responses for failed verifications or insufficient trust scores.
    • Includes a method add_trust_headers to inject local agent identity information into outgoing responses.
  • api/extensions/agentmesh/trust.py
    • Added TrustManager class to manage trust scores, peer verification, and workflow step authorization.
    • Maintains a cache for verified peers and dynamically adjusts trust scores based on successful or failed interactions.
    • Implements an audit log to record all trust-related decisions for traceability and compliance.
    • Defines TrustVerificationResult dataclass to encapsulate the outcome of trust verification, including verification status, trust score, and reason.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a trust layer for Dify agents, which is a great initiative for enhancing security in agent-to-agent communication. The implementation includes cryptographic identities, a trust manager, and middleware for enforcement. The code is well-structured. However, I've found a few critical and high-severity issues that need to be addressed. There's a critical security vulnerability in the fallback mechanism for when the cryptography library isn't available, which completely bypasses signature verification. Additionally, the capability checking logic, a core part of the authorization process, is flawed and doesn't support wildcards as intended. I've also noted a discrepancy between the documentation and the implementation regarding request signing. Please see my detailed comments for suggestions on how to resolve these issues.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new extensions.agentmesh trust-layer extension to the Dify API, providing agent identities, peer trust verification/scoring, and a Flask decorator/middleware interface intended to gate endpoints based on trust.

Changes:

  • Introduces CMVKIdentity / CMVKSignature for Ed25519-style agent identity and signing.
  • Adds TrustManager for peer verification, trust scoring, caching, and in-memory audit logging.
  • Adds TrustMiddleware and trust_required decorator plus initial extension documentation.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
api/extensions/agentmesh/trust.py Implements trust verification/scoring, cache, and audit log.
api/extensions/agentmesh/middleware.py Adds Flask decorator/middleware to enforce trust checks from headers.
api/extensions/agentmesh/identity.py Adds identity/signing primitives (Ed25519 when available).
api/extensions/agentmesh/init.py Exposes package-level imports for the extension.
api/extensions/agentmesh/README.md Documents installation, usage, headers, and configuration.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- verify_signature now fails securely when cryptography unavailable
- Capability wildcard matching (e.g., 'workflow:*') in has_capability()
- Thread safety: Added lock to TrustManager for all mutable state
- Cache now re-checks capabilities on every call (not just identity)
- Strict mode: require_headers=True option for trust_required decorator
- Export trust_required from __init__.py
- README: Clarify env vars and time decay are TODO
@imran-siddique
Copy link
Copy Markdown
Author

imran-siddique commented Feb 7, 2026

Addressed comments 🎉

/gemini review
/copilot

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Thanks for letting me know that you've addressed the comments! To request a new code review, please use the /gemini review command. I'm unable to automatically re-review without that explicit command.

@imran-siddique
Copy link
Copy Markdown
Author

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a valuable trust layer extension for Dify, enabling cryptographic identities and trust verification for agents. The code is well-structured across new modules for identity, trust management, and middleware. However, I've identified a critical security vulnerability: the implementation is missing signature verification for incoming requests, which undermines the core purpose of the trust layer. I've also included suggestions to improve error handling and reduce code duplication. Addressing the signature verification is crucial before this can be considered secure.

Comment on lines +66 to +116
def decorated_function(*args: Any, **kwargs: Any) -> Any:
trust_manager = cls.get_trust_manager()

if not trust_manager:
# Trust not configured, allow through
return f(*args, **kwargs)

# Extract trust headers
peer_did = request.headers.get("X-Agent-DID")
peer_public_key = request.headers.get("X-Agent-Public-Key")
peer_capabilities = request.headers.get("X-Agent-Capabilities", "").split(",")
peer_capabilities = [c.strip() for c in peer_capabilities if c.strip()]

if not peer_did:
if require_headers:
# Strict mode: reject requests without trust headers
return jsonify({
"error": "Trust headers required",
"reason": "Missing X-Agent-DID header",
}), 401
# Permissive mode: allow through (backward compatible)
return f(*args, **kwargs)

# Verify trust
result = trust_manager.verify_peer(
peer_did=peer_did,
peer_public_key=peer_public_key or "",
required_capabilities=required_capabilities,
peer_capabilities=peer_capabilities,
)

if not result.verified:
return jsonify({
"error": "Trust verification failed",
"reason": result.reason,
"trust_score": result.trust_score,
}), 403

if result.trust_score < min_score:
return jsonify({
"error": "Insufficient trust score",
"required": min_score,
"actual": result.trust_score,
}), 403

# Store verification result in request context
g.trust_verification = result
g.peer_did = peer_did

return f(*args, **kwargs)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

The trust_required decorator is missing a crucial security step: signature verification. The README.md mentions an X-Agent-Signature header, but the middleware does not read or validate it. Without signature verification, an agent can be impersonated by simply sending its public DID and public key, which defeats the purpose of a cryptographic trust layer. The request body (or a digest of it) should be signed by the calling agent's private key and verified here using its public key.

| `X-Agent-DID` | Agent's decentralized identifier |
| `X-Agent-Public-Key` | Base64-encoded Ed25519 public key |
| `X-Agent-Capabilities` | Comma-separated list of capabilities |
| `X-Agent-Signature` | Signature of request body (optional) |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The X-Agent-Signature header is documented as optional, but the current implementation in middleware.py does not process it at all. For a robust trust layer, verifying the request signature is critical to prevent impersonation and ensure message integrity. Please consider implementing the signature verification logic.

Comment on lines +139 to +140
except (InvalidSignature, ValueError, Exception):
return False
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The except (InvalidSignature, ValueError, Exception): clause is too broad. Catching the generic Exception can hide unrelated bugs and make debugging difficult. It's better to catch only the specific exceptions you expect from the cryptographic operations, such as InvalidSignature and ValueError. This ensures that unexpected errors are not silently swallowed.

Suggested change
except (InvalidSignature, ValueError, Exception):
return False
except (InvalidSignature, ValueError):
return False

Comment on lines +175 to +189
def _peer_has_capability(self, peer_caps: List[str], required: str) -> bool:
"""Check if peer has a required capability (supports wildcards)."""
for cap in peer_caps:
# Universal wildcard
if cap == "*":
return True
# Exact match
if cap == required:
return True
# Prefix wildcard (e.g., "workflow:*" matches "workflow:execute")
if cap.endswith(":*"):
prefix = cap[:-1] # "workflow:"
if required.startswith(prefix):
return True
return False
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The _peer_has_capability method duplicates the logic found in CMVKIdentity.has_capability. To adhere to the DRY (Don't Repeat Yourself) principle and avoid potential inconsistencies, this logic should be refactored into a single, reusable utility function. This function could be a static method or placed in a shared utility module.

- Remove overly broad Exception catch in verify_signature
- Extract capability_matches() utility function (DRY)
- Update README to clarify X-Agent-Signature is TODO
- Export capability_matches from __init__.py
Copilot AI review requested due to automatic review settings February 7, 2026 03:43
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +58 to +62
def set_identity(self, identity: CMVKIdentity) -> None:
"""Set or update the local identity."""
self.identity = identity
logger.info(f"Trust identity set: {identity.did}")

Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

logger.info(f"...") will violate the repo’s Ruff rule G004 (no f-strings in logging calls). Use logger interpolation (e.g., %s args) instead so lint passes.

Copilot uses AI. Check for mistakes.
Comment on lines +252 to +256
self._audit_log.append(entry)

# Keep log bounded
if len(self._audit_log) > 10000:
self._audit_log = self._audit_log[-5000:]
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

TrustManager is documented as thread-safe, but _log_audit mutates _audit_log (append + trimming) without holding _lock. This can race with get_audit_log() and lead to inconsistent/lost entries. Acquire _lock inside _log_audit (and keep trimming under the same lock) to make the thread-safety guarantee true.

Suggested change
self._audit_log.append(entry)
# Keep log bounded
if len(self._audit_log) > 10000:
self._audit_log = self._audit_log[-5000:]
# Mutate the audit log under the lock to preserve thread-safety.
with self._lock:
self._audit_log.append(entry)
# Keep log bounded
if len(self._audit_log) > 10000:
self._audit_log = self._audit_log[-5000:]

Copilot uses AI. Check for mistakes.
f"{workflow_id}:{step_id}"
)

trust_score = self._trust_scores.get(self.identity.did, 0.7)
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

verify_workflow_step() reads _trust_scores without holding _lock, even though other accesses are locked. This breaks the “thread-safe” guarantee and can race with record_success/record_failure. Read the score under _lock (and ideally log the audit entry under the same lock).

Copilot uses AI. Check for mistakes.
Comment on lines +90 to +94
# Calculate trust score
trust_score = self._calculate_trust_score(peer_did, peer_public_key)

if trust_score < self.min_trust_score:
return self._fail(
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

verify_peer() currently treats peer_did, peer_public_key, and X-Agent-Capabilities as self-asserted inputs and does not perform any cryptographic proof (e.g., request signature) that the caller controls the claimed key/DID. With the current scoring logic, any non-empty public key gets a passing default score (0.6), so this can be bypassed if used for authorization. Implement signature verification (e.g., X-Agent-Signature over canonical request data) and validate DID↔public-key binding, or avoid reporting the peer as “verified” without cryptographic proof.

Copilot uses AI. Check for mistakes.
Comment on lines +81 to +85
# Check identity cache (identity only, not capabilities)
cached = self._get_cached(peer_did)
if cached is not None:
return cached

Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

The verification cache is keyed only by peer_did. A caller can reuse a cached “verified” result by replaying the same DID with a different X-Agent-Public-Key, which becomes especially dangerous once real signature verification is added. Include the public key (and/or a key fingerprint) in the cache key, or ensure the provided public key matches what was previously verified before returning the cached result.

Copilot uses AI. Check for mistakes.
Comment on lines +53 to +57
self._verified_peers: Dict[str, Tuple[TrustVerificationResult, datetime]] = {}
self._trust_scores: Dict[str, float] = {} # DID -> score
self._lock = threading.Lock() # Protect mutable state
self._audit_log: List[Dict[str, Any]] = []

Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

Audit log and trust scores are stored only in in-memory process state (_audit_log, _trust_scores). In a typical multi-worker / multi-instance deployment, this will not be shared across workers and will be lost on restart, which undermines the “compliance audit logging” and trust scoring features. Consider persisting these to a shared store (DB/Redis/logstore) or clearly document that this is best-effort / dev-only.

Copilot uses AI. Check for mistakes.
Comment on lines +50 to +54
def require_trust(
cls,
min_score: float = 0.5,
required_capabilities: Optional[List[str]] = None,
require_headers: bool = False,
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

This introduces a new security-adjacent decorator/middleware path, but there are no tests covering header parsing, permissive vs strict mode, capability enforcement, and response status codes. Add unit tests for trust_required / TrustMiddleware.require_trust (and core TrustManager.verify_peer behavior) to prevent regressions.

Copilot uses AI. Check for mistakes.
Comment on lines +103 to +106
| `X-Agent-Signature` | Signature of request body (TODO: not yet verified by middleware) |

> **Note:** Request body signature verification (`X-Agent-Signature`) is documented for future implementation but is not currently enforced by the middleware. The current trust layer verifies identity presence and capabilities but does not cryptographically bind requests to the claimed identity.

Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

PR description claims “cryptographic identity and trust verification”, but the README notes that request signature verification (X-Agent-Signature) is not implemented/enforced by the middleware yet. Either implement signature verification as part of this PR, or adjust the PR description/wording so it doesn’t overstate the current security properties.

Copilot uses AI. Check for mistakes.
- Fix f-string logging (Ruff G004 violation)
- Make _log_audit thread-safe (acquire lock before mutation)
- Make verify_workflow_step read score under lock
- Include public key in cache key (prevent replay attacks)
- Document in-memory state limitations in README
@imran-siddique
Copy link
Copy Markdown
Author

All Review Comments Addressed ✅

I've addressed all the review feedback across multiple rounds:

Round 1-2 (Earlier):

  • Fixed fallback crypto behavior (now raises RuntimeError)
  • Fixed wildcard capability matching
  • Added capability_matches utility (DRY)
  • Fixed trust_required export in init.py

Round 3 (Latest):

  • Fixed f-string logging → %-formatting (Ruff G004)
  • Made _log_audit thread-safe (lock acquisition)
  • Made verify_workflow_step read scores under lock
  • Cache key now includes public key (security fix)
  • Documented in-memory state limitations in README

Acknowledged (Future Enhancements):

  • X-Agent-Signature verification → documented as TODO in README
  • did:key method for DID/public key binding → future enhancement
  • Unit tests → can add in follow-up PR

This has been a lot of back-and-forth. Could you please provide a final review so we can move forward? Thank you! 🙏

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new 'Trust Layer' extension for Dify, providing cryptographic identities and trust verification for agents. The implementation includes agent identity generation based on Ed25519, a trust manager for scoring and verification, and Flask middleware to protect API endpoints.

My review has identified a few critical security concerns. The most significant is the insecure fallback mechanism when the cryptography library is not installed, which could create a false sense of security. Additionally, the trust verification currently lacks request signature validation, which is a crucial component for a cryptographically secure trust layer. I've also included some suggestions for improving code robustness and performance.

Overall, this is a valuable feature, but the security aspects need to be addressed before it can be considered a reliable trust layer.

Comment on lines +119 to +122
else:
key_seed = hashlib.sha256(f"{did}:key".encode()).hexdigest()
private_key_b64 = base64.b64encode(key_seed[:32].encode()).decode('ascii')
public_key_b64 = base64.b64encode(key_seed[32:].encode()).decode('ascii')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

This fallback for key generation is insecure. It uses parts of a SHA256 hash as a 'private' and 'public' key, which is not a valid asymmetric key pair and provides no real security. This could create a false sense of security. The cryptography library should be a required dependency. If it's not available, this method should raise an error. A similar issue exists in the sign method's fallback.

Suggested change
else:
key_seed = hashlib.sha256(f"{did}:key".encode()).hexdigest()
private_key_b64 = base64.b64encode(key_seed[:32].encode()).decode('ascii')
public_key_b64 = base64.b64encode(key_seed[32:].encode()).decode('ascii')
else:
raise ImportError("The 'cryptography' library is required to generate identities.")

Comment on lines +63 to +112
def verify_peer(
self,
peer_did: str,
peer_public_key: str,
required_capabilities: Optional[List[str]] = None,
peer_capabilities: Optional[List[str]] = None,
) -> TrustVerificationResult:
"""Verify a peer agent's identity and capabilities."""
# Check capabilities first (always check, don't rely on identity-only cache)
peer_caps = peer_capabilities or []
if required_capabilities:
missing = []
for req_cap in required_capabilities:
if not self._peer_has_capability(peer_caps, req_cap):
missing.append(req_cap)
if missing:
return self._fail("Missing capabilities: %s" % missing, peer_did)

# Check identity cache - includes public key for security
cached = self._get_cached(peer_did, peer_public_key)
if cached is not None:
return cached

# Basic validation
if not peer_did or not peer_public_key:
return self._fail("Missing DID or public key", peer_did)

# Calculate trust score
trust_score = self._calculate_trust_score(peer_did, peer_public_key)

if trust_score < self.min_trust_score:
return self._fail(
"Trust score %.2f below minimum %.2f" % (trust_score, self.min_trust_score),
peer_did,
trust_score=trust_score
)

# Success
result = TrustVerificationResult(
verified=True,
trust_score=trust_score,
peer_did=peer_did,
reason="Verification successful",
verified_capabilities=peer_capabilities or [],
)

self._cache(peer_did, peer_public_key, result)
self._log_audit("verify_peer", peer_did, True, trust_score)

return result
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

The verify_peer method does not perform any cryptographic signature verification to confirm the peer's identity. It relies on headers (X-Agent-DID, X-Agent-Public-Key) that can be easily spoofed. This allows an attacker to impersonate any agent, undermining the security of the trust layer. While the README mentions that X-Agent-Signature verification is a TODO, this is a critical security gap that should be addressed to make this a true 'Trust Layer'.

app_id: Optional[str] = None,
) -> "CMVKIdentity":
"""Generate a new CMVK identity."""
seed = f"{name}:{tenant_id or ''}:{app_id or ''}:{time.time_ns()}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Using time.time_ns() as the main source of entropy for the DID seed can lead to predictable DIDs, especially if identities are generated in quick succession. For generating unique identifiers, it's better to use a cryptographically secure source of randomness. Consider adding secrets.token_hex(8) to the seed (you'll need to import secrets).

Suggested change
seed = f"{name}:{tenant_id or ''}:{app_id or ''}:{time.time_ns()}"
seed = f"{name}:{tenant_id or ''}:{app_id or ''}:{time.time_ns()}:{secrets.token_hex(8)}"

Comment on lines +259 to +261
# Keep log bounded
if len(self._audit_log) > 10000:
self._audit_log = self._audit_log[-5000:]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Manually truncating the audit log list like this can be inefficient for large logs, as it creates a new list slice in memory. A more idiomatic and performant approach for a fixed-size log is to use collections.deque with a maxlen. You would need to change the type of _audit_log in __init__ to deque(maxlen=10000) and then you can remove this block.

@crazywoola
Copy link
Copy Markdown
Member

You should submit it as a plugin. Please refer to the documentation at https://docs.dify.ai/en/develop-plugin/getting-started/getting-started-dify-plugin for plugin submission. Our main repository no longer accepts third-party plugin submissions. You should package the developed plugin and submit it to this repository: https://github.com/langgenius/dify-plugins/pulls

@crazywoola crazywoola closed this Feb 7, 2026
@imran-siddique
Copy link
Copy Markdown
Author

Thank you for the guidance @crazywoola! Following your recommendation, we've created a Dify plugin:

📦 AgentMesh Trust Layer Plugin

The plugin provides 4 tools for cryptographic trust verification in multi-agent workflows:

  • verify_peer - Verify another agent's identity and capabilities before trusting their data
  • verify_step - Check authorization for workflow step execution
  • get_identity - Get this agent's cryptographic identity to share with peers
  • record_interaction - Record success/failure to update trust scores dynamically

We'll submit a PR to the dify-plugins repo shortly. Thanks for the great plugin architecture!

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

Labels

💪 enhancement New feature or request size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants