agentmesh-platform 1.0.0a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentmesh/__init__.py +119 -0
- agentmesh/cli/__init__.py +10 -0
- agentmesh/cli/main.py +405 -0
- agentmesh/governance/__init__.py +26 -0
- agentmesh/governance/audit.py +381 -0
- agentmesh/governance/compliance.py +447 -0
- agentmesh/governance/policy.py +385 -0
- agentmesh/governance/shadow.py +266 -0
- agentmesh/identity/__init__.py +30 -0
- agentmesh/identity/agent_id.py +319 -0
- agentmesh/identity/credentials.py +323 -0
- agentmesh/identity/delegation.py +281 -0
- agentmesh/identity/risk.py +279 -0
- agentmesh/identity/spiffe.py +230 -0
- agentmesh/identity/sponsor.py +178 -0
- agentmesh/reward/__init__.py +19 -0
- agentmesh/reward/engine.py +454 -0
- agentmesh/reward/learning.py +287 -0
- agentmesh/reward/scoring.py +203 -0
- agentmesh/trust/__init__.py +19 -0
- agentmesh/trust/bridge.py +386 -0
- agentmesh/trust/capability.py +293 -0
- agentmesh/trust/handshake.py +334 -0
- agentmesh_platform-1.0.0a1.dist-info/METADATA +332 -0
- agentmesh_platform-1.0.0a1.dist-info/RECORD +28 -0
- agentmesh_platform-1.0.0a1.dist-info/WHEEL +4 -0
- agentmesh_platform-1.0.0a1.dist-info/entry_points.txt +2 -0
- agentmesh_platform-1.0.0a1.dist-info/licenses/LICENSE +190 -0
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Trust Handshake
|
|
3
|
+
|
|
4
|
+
IATP-compatible trust handshakes for cross-agent and cross-cloud
|
|
5
|
+
communication. Handshake completes in <200ms.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
from typing import Optional, Literal
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
import hashlib
|
|
12
|
+
import secrets
|
|
13
|
+
import asyncio
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class HandshakeChallenge(BaseModel):
|
|
17
|
+
"""Challenge issued during trust handshake."""
|
|
18
|
+
|
|
19
|
+
challenge_id: str
|
|
20
|
+
nonce: str
|
|
21
|
+
timestamp: datetime = Field(default_factory=datetime.utcnow)
|
|
22
|
+
expires_in_seconds: int = 30
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def generate(cls) -> "HandshakeChallenge":
|
|
26
|
+
"""Generate a new challenge."""
|
|
27
|
+
return cls(
|
|
28
|
+
challenge_id=f"challenge_{secrets.token_hex(8)}",
|
|
29
|
+
nonce=secrets.token_hex(32),
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
def is_expired(self) -> bool:
|
|
33
|
+
"""Check if challenge has expired."""
|
|
34
|
+
elapsed = (datetime.utcnow() - self.timestamp).total_seconds()
|
|
35
|
+
return elapsed > self.expires_in_seconds
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class HandshakeResponse(BaseModel):
|
|
39
|
+
"""Response to a handshake challenge."""
|
|
40
|
+
|
|
41
|
+
challenge_id: str
|
|
42
|
+
response_nonce: str
|
|
43
|
+
|
|
44
|
+
# Agent attestation
|
|
45
|
+
agent_did: str
|
|
46
|
+
capabilities: list[str] = Field(default_factory=list)
|
|
47
|
+
trust_score: int = Field(default=0, ge=0, le=1000)
|
|
48
|
+
|
|
49
|
+
# Cryptographic proof
|
|
50
|
+
signature: str # Signature over challenge + response
|
|
51
|
+
public_key: str # For verification
|
|
52
|
+
|
|
53
|
+
# Metadata
|
|
54
|
+
timestamp: datetime = Field(default_factory=datetime.utcnow)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class HandshakeResult(BaseModel):
|
|
58
|
+
"""Result of a trust handshake."""
|
|
59
|
+
|
|
60
|
+
verified: bool
|
|
61
|
+
peer_did: str
|
|
62
|
+
peer_name: Optional[str] = None
|
|
63
|
+
|
|
64
|
+
# Trust details
|
|
65
|
+
trust_score: int = Field(default=0, ge=0, le=1000)
|
|
66
|
+
trust_level: Literal["verified_partner", "trusted", "standard", "untrusted"] = "untrusted"
|
|
67
|
+
|
|
68
|
+
# Capabilities
|
|
69
|
+
capabilities: list[str] = Field(default_factory=list)
|
|
70
|
+
|
|
71
|
+
# Timing
|
|
72
|
+
handshake_started: datetime = Field(default_factory=datetime.utcnow)
|
|
73
|
+
handshake_completed: Optional[datetime] = None
|
|
74
|
+
latency_ms: Optional[int] = None
|
|
75
|
+
|
|
76
|
+
# Rejection reason (if not verified)
|
|
77
|
+
rejection_reason: Optional[str] = None
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def success(
|
|
81
|
+
cls,
|
|
82
|
+
peer_did: str,
|
|
83
|
+
trust_score: int,
|
|
84
|
+
capabilities: list[str],
|
|
85
|
+
peer_name: Optional[str] = None,
|
|
86
|
+
started: Optional[datetime] = None,
|
|
87
|
+
) -> "HandshakeResult":
|
|
88
|
+
"""Create a successful handshake result."""
|
|
89
|
+
now = datetime.utcnow()
|
|
90
|
+
start = started or now
|
|
91
|
+
latency = int((now - start).total_seconds() * 1000)
|
|
92
|
+
|
|
93
|
+
# Determine trust level
|
|
94
|
+
if trust_score >= 900:
|
|
95
|
+
level = "verified_partner"
|
|
96
|
+
elif trust_score >= 700:
|
|
97
|
+
level = "trusted"
|
|
98
|
+
elif trust_score >= 400:
|
|
99
|
+
level = "standard"
|
|
100
|
+
else:
|
|
101
|
+
level = "untrusted"
|
|
102
|
+
|
|
103
|
+
return cls(
|
|
104
|
+
verified=True,
|
|
105
|
+
peer_did=peer_did,
|
|
106
|
+
peer_name=peer_name,
|
|
107
|
+
trust_score=trust_score,
|
|
108
|
+
trust_level=level,
|
|
109
|
+
capabilities=capabilities,
|
|
110
|
+
handshake_started=start,
|
|
111
|
+
handshake_completed=now,
|
|
112
|
+
latency_ms=latency,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
@classmethod
|
|
116
|
+
def failure(
|
|
117
|
+
cls,
|
|
118
|
+
peer_did: str,
|
|
119
|
+
reason: str,
|
|
120
|
+
started: Optional[datetime] = None,
|
|
121
|
+
) -> "HandshakeResult":
|
|
122
|
+
"""Create a failed handshake result."""
|
|
123
|
+
now = datetime.utcnow()
|
|
124
|
+
start = started or now
|
|
125
|
+
latency = int((now - start).total_seconds() * 1000)
|
|
126
|
+
|
|
127
|
+
return cls(
|
|
128
|
+
verified=False,
|
|
129
|
+
peer_did=peer_did,
|
|
130
|
+
trust_score=0,
|
|
131
|
+
handshake_started=start,
|
|
132
|
+
handshake_completed=now,
|
|
133
|
+
latency_ms=latency,
|
|
134
|
+
rejection_reason=reason,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class TrustHandshake:
|
|
139
|
+
"""
|
|
140
|
+
Implements IATP trust handshakes.
|
|
141
|
+
|
|
142
|
+
The handshake verifies:
|
|
143
|
+
1. Agent identity (via signature verification)
|
|
144
|
+
2. Trust score (from registry/Nexus)
|
|
145
|
+
3. Capabilities (attestation)
|
|
146
|
+
|
|
147
|
+
Target: <200ms for cross-cloud handshakes.
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
MAX_HANDSHAKE_MS = 200
|
|
151
|
+
|
|
152
|
+
def __init__(self, agent_did: str):
|
|
153
|
+
self.agent_did = agent_did
|
|
154
|
+
self._pending_challenges: dict[str, HandshakeChallenge] = {}
|
|
155
|
+
|
|
156
|
+
async def initiate(
|
|
157
|
+
self,
|
|
158
|
+
peer_did: str,
|
|
159
|
+
protocol: str = "iatp",
|
|
160
|
+
required_trust_score: int = 700,
|
|
161
|
+
required_capabilities: Optional[list[str]] = None,
|
|
162
|
+
) -> HandshakeResult:
|
|
163
|
+
"""
|
|
164
|
+
Initiate a trust handshake with a peer.
|
|
165
|
+
|
|
166
|
+
Three-phase handshake:
|
|
167
|
+
1. Challenge: Send nonce to peer
|
|
168
|
+
2. Response: Peer signs nonce + attestation
|
|
169
|
+
3. Verification: Verify signature + trust score
|
|
170
|
+
"""
|
|
171
|
+
start = datetime.utcnow()
|
|
172
|
+
|
|
173
|
+
try:
|
|
174
|
+
# Phase 1: Generate and send challenge
|
|
175
|
+
challenge = HandshakeChallenge.generate()
|
|
176
|
+
self._pending_challenges[challenge.challenge_id] = challenge
|
|
177
|
+
|
|
178
|
+
# Phase 2: Get response (would be async HTTP in production)
|
|
179
|
+
response = await self._get_peer_response(peer_did, challenge)
|
|
180
|
+
|
|
181
|
+
if not response:
|
|
182
|
+
return HandshakeResult.failure(
|
|
183
|
+
peer_did, "No response from peer", start
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
# Phase 3: Verify response
|
|
187
|
+
verification = await self._verify_response(
|
|
188
|
+
response, challenge, required_trust_score, required_capabilities
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
if not verification["valid"]:
|
|
192
|
+
return HandshakeResult.failure(
|
|
193
|
+
peer_did, verification["reason"], start
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
return HandshakeResult.success(
|
|
197
|
+
peer_did=peer_did,
|
|
198
|
+
trust_score=response.trust_score,
|
|
199
|
+
capabilities=response.capabilities,
|
|
200
|
+
started=start,
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
except asyncio.TimeoutError:
|
|
204
|
+
return HandshakeResult.failure(
|
|
205
|
+
peer_did, "Handshake timeout", start
|
|
206
|
+
)
|
|
207
|
+
except Exception as e:
|
|
208
|
+
return HandshakeResult.failure(
|
|
209
|
+
peer_did, f"Handshake error: {str(e)}", start
|
|
210
|
+
)
|
|
211
|
+
finally:
|
|
212
|
+
# Cleanup
|
|
213
|
+
if challenge.challenge_id in self._pending_challenges:
|
|
214
|
+
del self._pending_challenges[challenge.challenge_id]
|
|
215
|
+
|
|
216
|
+
async def respond(
|
|
217
|
+
self,
|
|
218
|
+
challenge: HandshakeChallenge,
|
|
219
|
+
my_capabilities: list[str],
|
|
220
|
+
my_trust_score: int,
|
|
221
|
+
private_key: any, # Ed25519 private key
|
|
222
|
+
) -> HandshakeResponse:
|
|
223
|
+
"""
|
|
224
|
+
Respond to a trust handshake challenge.
|
|
225
|
+
|
|
226
|
+
Signs the challenge with our private key and attests capabilities.
|
|
227
|
+
"""
|
|
228
|
+
# Check challenge not expired
|
|
229
|
+
if challenge.is_expired():
|
|
230
|
+
raise ValueError("Challenge expired")
|
|
231
|
+
|
|
232
|
+
# Generate response nonce
|
|
233
|
+
response_nonce = secrets.token_hex(16)
|
|
234
|
+
|
|
235
|
+
# Create signature payload
|
|
236
|
+
payload = f"{challenge.challenge_id}:{challenge.nonce}:{response_nonce}:{self.agent_did}"
|
|
237
|
+
|
|
238
|
+
# Sign (would use actual Ed25519 in production)
|
|
239
|
+
signature = hashlib.sha256(payload.encode()).hexdigest()
|
|
240
|
+
|
|
241
|
+
return HandshakeResponse(
|
|
242
|
+
challenge_id=challenge.challenge_id,
|
|
243
|
+
response_nonce=response_nonce,
|
|
244
|
+
agent_did=self.agent_did,
|
|
245
|
+
capabilities=my_capabilities,
|
|
246
|
+
trust_score=my_trust_score,
|
|
247
|
+
signature=signature,
|
|
248
|
+
public_key="placeholder_public_key",
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
async def _get_peer_response(
|
|
252
|
+
self,
|
|
253
|
+
peer_did: str,
|
|
254
|
+
challenge: HandshakeChallenge,
|
|
255
|
+
) -> Optional[HandshakeResponse]:
|
|
256
|
+
"""
|
|
257
|
+
Send challenge to peer and get response.
|
|
258
|
+
|
|
259
|
+
In production, this would:
|
|
260
|
+
1. Resolve peer DID to endpoint
|
|
261
|
+
2. POST challenge to peer's IATP endpoint
|
|
262
|
+
3. Receive and parse response
|
|
263
|
+
"""
|
|
264
|
+
# Simulate peer response for now
|
|
265
|
+
# In production, would make HTTP request to peer
|
|
266
|
+
await asyncio.sleep(0.05) # Simulate network latency
|
|
267
|
+
|
|
268
|
+
return HandshakeResponse(
|
|
269
|
+
challenge_id=challenge.challenge_id,
|
|
270
|
+
response_nonce=secrets.token_hex(16),
|
|
271
|
+
agent_did=peer_did,
|
|
272
|
+
capabilities=["read:data", "write:reports"],
|
|
273
|
+
trust_score=750,
|
|
274
|
+
signature="simulated_signature",
|
|
275
|
+
public_key="simulated_public_key",
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
async def _verify_response(
|
|
279
|
+
self,
|
|
280
|
+
response: HandshakeResponse,
|
|
281
|
+
challenge: HandshakeChallenge,
|
|
282
|
+
required_score: int,
|
|
283
|
+
required_capabilities: Optional[list[str]],
|
|
284
|
+
) -> dict:
|
|
285
|
+
"""
|
|
286
|
+
Verify a handshake response.
|
|
287
|
+
|
|
288
|
+
Checks:
|
|
289
|
+
1. Challenge ID matches
|
|
290
|
+
2. Signature is valid
|
|
291
|
+
3. Trust score meets threshold
|
|
292
|
+
4. Required capabilities present
|
|
293
|
+
"""
|
|
294
|
+
# Verify challenge ID
|
|
295
|
+
if response.challenge_id != challenge.challenge_id:
|
|
296
|
+
return {"valid": False, "reason": "Challenge ID mismatch"}
|
|
297
|
+
|
|
298
|
+
# Verify not expired
|
|
299
|
+
if challenge.is_expired():
|
|
300
|
+
return {"valid": False, "reason": "Challenge expired"}
|
|
301
|
+
|
|
302
|
+
# Verify signature (simplified - would verify Ed25519 in production)
|
|
303
|
+
# In production: verify response.signature against response.public_key
|
|
304
|
+
|
|
305
|
+
# Verify trust score
|
|
306
|
+
if response.trust_score < required_score:
|
|
307
|
+
return {
|
|
308
|
+
"valid": False,
|
|
309
|
+
"reason": f"Trust score {response.trust_score} below required {required_score}"
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
# Verify capabilities
|
|
313
|
+
if required_capabilities:
|
|
314
|
+
missing = set(required_capabilities) - set(response.capabilities)
|
|
315
|
+
if missing:
|
|
316
|
+
return {
|
|
317
|
+
"valid": False,
|
|
318
|
+
"reason": f"Missing capabilities: {missing}"
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return {"valid": True, "reason": None}
|
|
322
|
+
|
|
323
|
+
def create_challenge(self) -> HandshakeChallenge:
|
|
324
|
+
"""Create a new challenge for incoming handshake."""
|
|
325
|
+
challenge = HandshakeChallenge.generate()
|
|
326
|
+
self._pending_challenges[challenge.challenge_id] = challenge
|
|
327
|
+
return challenge
|
|
328
|
+
|
|
329
|
+
def validate_challenge(self, challenge_id: str) -> bool:
|
|
330
|
+
"""Check if a challenge ID is valid and pending."""
|
|
331
|
+
challenge = self._pending_challenges.get(challenge_id)
|
|
332
|
+
if not challenge:
|
|
333
|
+
return False
|
|
334
|
+
return not challenge.is_expired()
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentmesh-platform
|
|
3
|
+
Version: 1.0.0a1
|
|
4
|
+
Summary: The Secure Nervous System for Cloud-Native Agent Ecosystems - Identity, Trust, Reward, Governance
|
|
5
|
+
Project-URL: Homepage, https://github.com/imran-siddique/agent-mesh
|
|
6
|
+
Project-URL: Documentation, https://github.com/imran-siddique/agent-mesh#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/imran-siddique/agent-mesh
|
|
8
|
+
Project-URL: Issues, https://github.com/imran-siddique/agent-mesh/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/imran-siddique/agent-mesh/blob/master/CHANGELOG.md
|
|
10
|
+
Author-email: Imran Siddique <imran.siddique@microsoft.com>
|
|
11
|
+
License: Apache-2.0
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: a2a,agents,ai,compliance,eu-ai-act,governance,hipaa,iatp,identity,mcp,security,soc2,trust,zero-trust
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: Information Technology
|
|
17
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Security
|
|
22
|
+
Classifier: Topic :: Security :: Cryptography
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Topic :: System :: Systems Administration :: Authentication/Directory
|
|
25
|
+
Requires-Python: >=3.11
|
|
26
|
+
Requires-Dist: agent-os-kernel[iatp,nexus]>=1.2.0
|
|
27
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
28
|
+
Requires-Dist: click>=8.1.0
|
|
29
|
+
Requires-Dist: cryptography>=42.0.0
|
|
30
|
+
Requires-Dist: httpx>=0.26.0
|
|
31
|
+
Requires-Dist: pydantic>=2.5.0
|
|
32
|
+
Requires-Dist: pynacl>=1.5.0
|
|
33
|
+
Requires-Dist: pyyaml>=6.0
|
|
34
|
+
Requires-Dist: rich>=13.0.0
|
|
35
|
+
Requires-Dist: structlog>=24.1.0
|
|
36
|
+
Provides-Extra: dev
|
|
37
|
+
Requires-Dist: black>=24.1.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: mypy>=1.8.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
|
|
41
|
+
Requires-Dist: pytest>=7.4.0; extra == 'dev'
|
|
42
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
43
|
+
Provides-Extra: server
|
|
44
|
+
Requires-Dist: fastapi>=0.109.0; extra == 'server'
|
|
45
|
+
Requires-Dist: uvicorn[standard]>=0.27.0; extra == 'server'
|
|
46
|
+
Description-Content-Type: text/markdown
|
|
47
|
+
|
|
48
|
+
# AgentMesh
|
|
49
|
+
|
|
50
|
+
**The Secure Nervous System for Cloud-Native Agent Ecosystems**
|
|
51
|
+
|
|
52
|
+
*Identity · Trust · Reward · Governance*
|
|
53
|
+
|
|
54
|
+
[](LICENSE)
|
|
55
|
+
[](https://python.org)
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Overview
|
|
60
|
+
|
|
61
|
+
AgentMesh is the first platform purpose-built for the **Governed Agent Mesh** — the cloud-native, multi-vendor network of AI agents that will define enterprise operations.
|
|
62
|
+
|
|
63
|
+
The protocols exist (A2A, MCP, IATP). The agents are shipping. **The trust layer does not.** AgentMesh fills that gap.
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
67
|
+
│ AGENTMESH ARCHITECTURE │
|
|
68
|
+
├─────────────────────────────────────────────────────────────────────────────┤
|
|
69
|
+
│ LAYER 4 │ Reward & Learning Engine │
|
|
70
|
+
│ │ Per-agent trust scores · Multi-dimensional rewards · Adaptive │
|
|
71
|
+
├───────────┼─────────────────────────────────────────────────────────────────┤
|
|
72
|
+
│ LAYER 3 │ Governance & Compliance Plane │
|
|
73
|
+
│ │ Policy engine · EU AI Act / SOC2 / HIPAA · Merkle audit logs │
|
|
74
|
+
├───────────┼─────────────────────────────────────────────────────────────────┤
|
|
75
|
+
│ LAYER 2 │ Trust & Protocol Bridge │
|
|
76
|
+
│ │ A2A · MCP · IATP · Protocol translation · Capability scoping │
|
|
77
|
+
├───────────┼─────────────────────────────────────────────────────────────────┤
|
|
78
|
+
│ LAYER 1 │ Identity & Zero-Trust Core │
|
|
79
|
+
│ │ Agent CA · Ephemeral creds · SPIFFE/SVID · Human sponsors │
|
|
80
|
+
└───────────┴─────────────────────────────────────────────────────────────────┘
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Why AgentMesh?
|
|
84
|
+
|
|
85
|
+
### The Problem
|
|
86
|
+
|
|
87
|
+
- **40:1 to 100:1** — Non-human identities now outnumber human identities in enterprises
|
|
88
|
+
- **AI agents** are the fastest-growing, least-governed identity category
|
|
89
|
+
- **A2A gives agents a common language. MCP gives agents tools. Neither enforces trust.**
|
|
90
|
+
|
|
91
|
+
### The Solution
|
|
92
|
+
|
|
93
|
+
AgentMesh provides:
|
|
94
|
+
|
|
95
|
+
| Capability | Description |
|
|
96
|
+
|------------|-------------|
|
|
97
|
+
| **Agent Identity** | First-class identity with human sponsor accountability |
|
|
98
|
+
| **Ephemeral Credentials** | 15-minute TTL by default, auto-rotation |
|
|
99
|
+
| **Protocol Bridge** | Native A2A, MCP, IATP with unified trust model |
|
|
100
|
+
| **Reward Engine** | Continuous behavioral scoring, not static rules |
|
|
101
|
+
| **Compliance Automation** | EU AI Act, SOC 2, HIPAA, GDPR mapping |
|
|
102
|
+
|
|
103
|
+
## Quick Start
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Install AgentMesh CLI
|
|
107
|
+
pip install agentmesh
|
|
108
|
+
|
|
109
|
+
# Initialize a governed agent in 30 seconds
|
|
110
|
+
agentmesh init --name my-agent --sponsor alice@company.com
|
|
111
|
+
|
|
112
|
+
# Register with the mesh
|
|
113
|
+
agentmesh register
|
|
114
|
+
|
|
115
|
+
# Start with governance enabled
|
|
116
|
+
agentmesh run
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Installation
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
pip install agentmesh
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Or from source:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
git clone https://github.com/imran-siddique/agent-mesh.git
|
|
129
|
+
cd agent-mesh
|
|
130
|
+
pip install -e .
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Core Concepts
|
|
134
|
+
|
|
135
|
+
### 1. Agent Identity
|
|
136
|
+
|
|
137
|
+
Every agent gets a unique, cryptographically bound identity:
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
from agentmesh import AgentIdentity
|
|
141
|
+
|
|
142
|
+
identity = AgentIdentity.create(
|
|
143
|
+
name="data-analyst-agent",
|
|
144
|
+
sponsor="alice@company.com", # Human accountability
|
|
145
|
+
capabilities=["read:data", "write:reports"],
|
|
146
|
+
)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 2. Delegation Chains
|
|
150
|
+
|
|
151
|
+
Agents can delegate to sub-agents, but scope **always narrows**:
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
# Parent agent delegates to child
|
|
155
|
+
child_identity = parent_identity.delegate(
|
|
156
|
+
name="summarizer-subagent",
|
|
157
|
+
capabilities=["read:data"], # Subset of parent's capabilities
|
|
158
|
+
)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 3. Trust Handshakes (IATP)
|
|
162
|
+
|
|
163
|
+
Cross-agent communication requires trust verification:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from agentmesh import TrustBridge
|
|
167
|
+
|
|
168
|
+
bridge = TrustBridge()
|
|
169
|
+
|
|
170
|
+
# Verify peer before communication
|
|
171
|
+
verification = await bridge.verify_peer(
|
|
172
|
+
peer_id="did:mesh:other-agent",
|
|
173
|
+
required_trust_score=700,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
if verification.verified:
|
|
177
|
+
await bridge.send_message(peer_id, message)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### 4. Reward Scoring
|
|
181
|
+
|
|
182
|
+
Every action is scored across multiple dimensions:
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
from agentmesh import RewardEngine
|
|
186
|
+
|
|
187
|
+
engine = RewardEngine()
|
|
188
|
+
|
|
189
|
+
# Actions are automatically scored
|
|
190
|
+
score = engine.get_agent_score("did:mesh:my-agent")
|
|
191
|
+
# {
|
|
192
|
+
# "total": 847,
|
|
193
|
+
# "dimensions": {
|
|
194
|
+
# "policy_compliance": 95,
|
|
195
|
+
# "resource_efficiency": 82,
|
|
196
|
+
# "output_quality": 88,
|
|
197
|
+
# "security_posture": 91,
|
|
198
|
+
# "collaboration_health": 84
|
|
199
|
+
# }
|
|
200
|
+
# }
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 5. Policy Engine
|
|
204
|
+
|
|
205
|
+
Declarative governance policies:
|
|
206
|
+
|
|
207
|
+
```yaml
|
|
208
|
+
# policy.yaml
|
|
209
|
+
version: "1.0"
|
|
210
|
+
agent: "data-analyst-agent"
|
|
211
|
+
|
|
212
|
+
rules:
|
|
213
|
+
- name: "no-pii-export"
|
|
214
|
+
condition: "action.type == 'export' and data.contains_pii"
|
|
215
|
+
action: "deny"
|
|
216
|
+
|
|
217
|
+
- name: "rate-limit-api"
|
|
218
|
+
condition: "action.type == 'api_call'"
|
|
219
|
+
limit: "100/hour"
|
|
220
|
+
|
|
221
|
+
- name: "require-approval-for-delete"
|
|
222
|
+
condition: "action.type == 'delete'"
|
|
223
|
+
action: "require_approval"
|
|
224
|
+
approvers: ["security-team"]
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Protocol Support
|
|
228
|
+
|
|
229
|
+
| Protocol | Status | Description |
|
|
230
|
+
|----------|--------|-------------|
|
|
231
|
+
| A2A | ✅ Alpha | Agent-to-agent coordination |
|
|
232
|
+
| MCP | ✅ Alpha | Tool and resource binding |
|
|
233
|
+
| IATP | ✅ Alpha | Trust handshakes (via agent-os) |
|
|
234
|
+
| ACP | 🔄 Beta | Lightweight messaging |
|
|
235
|
+
| SPIFFE | ✅ Alpha | Workload identity |
|
|
236
|
+
|
|
237
|
+
## Architecture
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
agentmesh/
|
|
241
|
+
├── identity/ # Layer 1: Identity & Zero-Trust
|
|
242
|
+
│ ├── agent_id.py # Agent identity management
|
|
243
|
+
│ ├── credentials.py # Ephemeral credential issuance
|
|
244
|
+
│ ├── delegation.py # Delegation chains
|
|
245
|
+
│ └── spiffe.py # SPIFFE/SVID integration
|
|
246
|
+
│
|
|
247
|
+
├── trust/ # Layer 2: Trust & Protocol Bridge
|
|
248
|
+
│ ├── bridge.py # Protocol bridge
|
|
249
|
+
│ ├── handshake.py # Trust handshakes
|
|
250
|
+
│ └── capability.py # Capability scoping
|
|
251
|
+
│
|
|
252
|
+
├── protocols/ # Protocol implementations
|
|
253
|
+
│ ├── a2a/ # A2A support
|
|
254
|
+
│ ├── mcp/ # MCP support
|
|
255
|
+
│ └── iatp/ # IATP (uses agent-os)
|
|
256
|
+
│
|
|
257
|
+
├── governance/ # Layer 3: Governance & Compliance
|
|
258
|
+
│ ├── policy.py # Policy engine
|
|
259
|
+
│ ├── compliance.py # Compliance mapping
|
|
260
|
+
│ ├── audit.py # Merkle-chained audit logs
|
|
261
|
+
│ └── shadow.py # Shadow mode
|
|
262
|
+
│
|
|
263
|
+
├── reward/ # Layer 4: Reward & Learning
|
|
264
|
+
│ ├── engine.py # Reward engine
|
|
265
|
+
│ ├── scoring.py # Multi-dimensional scoring
|
|
266
|
+
│ └── learning.py # Adaptive learning
|
|
267
|
+
│
|
|
268
|
+
├── cli/ # Command-line interface
|
|
269
|
+
└── sdk/ # Python SDK
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Compliance
|
|
273
|
+
|
|
274
|
+
AgentMesh automates compliance mapping for:
|
|
275
|
+
|
|
276
|
+
- **EU AI Act** — Risk classification, transparency requirements
|
|
277
|
+
- **SOC 2** — Security, availability, processing integrity
|
|
278
|
+
- **HIPAA** — PHI handling, audit controls
|
|
279
|
+
- **GDPR** — Data processing, consent, right to explanation
|
|
280
|
+
|
|
281
|
+
```python
|
|
282
|
+
from agentmesh import ComplianceEngine
|
|
283
|
+
|
|
284
|
+
compliance = ComplianceEngine(frameworks=["soc2", "hipaa"])
|
|
285
|
+
|
|
286
|
+
# Generate compliance report
|
|
287
|
+
report = compliance.generate_report(
|
|
288
|
+
agent_id="did:mesh:healthcare-agent",
|
|
289
|
+
period="2026-01",
|
|
290
|
+
)
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Threat Model
|
|
294
|
+
|
|
295
|
+
| Threat | AgentMesh Defense |
|
|
296
|
+
|--------|-------------------|
|
|
297
|
+
| Prompt Injection | Tool output sanitized at Protocol Bridge |
|
|
298
|
+
| Credential Theft | 15-min TTL, instant revocation on trust breach |
|
|
299
|
+
| Shadow Agents | Unregistered agents blocked at network layer |
|
|
300
|
+
| Delegation Escalation | Chains are cryptographically narrowing |
|
|
301
|
+
| Cascade Failure | Per-agent trust scoring isolates blast radius |
|
|
302
|
+
|
|
303
|
+
## Roadmap
|
|
304
|
+
|
|
305
|
+
| Phase | Timeline | Deliverables |
|
|
306
|
+
|-------|----------|--------------|
|
|
307
|
+
| Alpha | Q1 2026 | Identity Core, A2A+MCP bridge, CLI |
|
|
308
|
+
| Beta | Q2 2026 | IATP handshake, Reward Engine v1, Dashboard |
|
|
309
|
+
| GA | Q3 2026 | Compliance automation, Enterprise features |
|
|
310
|
+
| Scale | Q4 2026 | Agent Marketplace, Partner integrations |
|
|
311
|
+
|
|
312
|
+
## Dependencies
|
|
313
|
+
|
|
314
|
+
AgentMesh builds on:
|
|
315
|
+
|
|
316
|
+
- **[agent-os](https://github.com/imran-siddique/agent-os)** — IATP protocol, Nexus trust exchange
|
|
317
|
+
- **SPIFFE/SPIRE** — Workload identity
|
|
318
|
+
- **OpenTelemetry** — Observability
|
|
319
|
+
|
|
320
|
+
## Contributing
|
|
321
|
+
|
|
322
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
323
|
+
|
|
324
|
+
## License
|
|
325
|
+
|
|
326
|
+
Apache 2.0 — See [LICENSE](LICENSE) for details.
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
**Agents shouldn't be islands. But they also shouldn't be ungoverned.**
|
|
331
|
+
|
|
332
|
+
*AgentMesh is the trust layer that makes the mesh safe enough to scale.*
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
agentmesh/__init__.py,sha256=kZu_8m1IuUu24dS4O7Ba-Dfr3vaPqd6zH3dez1gZBUk,2414
|
|
2
|
+
agentmesh/cli/__init__.py,sha256=mwZuqtifIxKGbSy3p_0hhuGdxb1kttg7b84c9kfUAkk,208
|
|
3
|
+
agentmesh/cli/main.py,sha256=xTZ6TTQ_yQGzw6T2YiyAjtDsA5hLfPVzoRuJodbs8wY,13209
|
|
4
|
+
agentmesh/governance/__init__.py,sha256=WL3JiY-wwnZCMHLfl0eA4o11vfeXvvZ7OAL4J6-mvJY,702
|
|
5
|
+
agentmesh/governance/audit.py,sha256=T85ToKmoyUoYsBDLHHddQHOzg8osbPtM3CEC_ufH2PU,11795
|
|
6
|
+
agentmesh/governance/compliance.py,sha256=LIAQt0jy2UuoN6K9oMMJKMEpTCAqYguGYGzZvbRkE6Q,15843
|
|
7
|
+
agentmesh/governance/policy.py,sha256=5rkDf6UVmomQZTUabjDwzGL9XHjvw6w_kw60GrfOR9g,12412
|
|
8
|
+
agentmesh/governance/shadow.py,sha256=Mw20pjq1ew6VBcRd7eXCRpoU5zElGcazwhksQxEcI38,9085
|
|
9
|
+
agentmesh/identity/__init__.py,sha256=xQFwY-C5e35VF61oSOKgzJMTqTWv-VUArej74G8HFU8,748
|
|
10
|
+
agentmesh/identity/agent_id.py,sha256=iCIPCpBRsiCyFjT2rFwxZgYfgTxGYstnX8EQfIk6Sjg,11657
|
|
11
|
+
agentmesh/identity/credentials.py,sha256=yksJbQAzBBwiacOu-Wl7Pg1diNxX68_sjlUCyVtPvp8,11458
|
|
12
|
+
agentmesh/identity/delegation.py,sha256=t74Ly9SHqY_4Y8pRTjgPycfayr2_iMQ5oIfLbLYVkYY,10441
|
|
13
|
+
agentmesh/identity/risk.py,sha256=Fb531ECeKA5RfCUFAQS9Qd4qiqPeXuDexBT19m0uO_Q,9749
|
|
14
|
+
agentmesh/identity/spiffe.py,sha256=f7HzeD13WGzxYVoJDaQwmWW_cZ2qi5D6IVroRJhNvn0,7426
|
|
15
|
+
agentmesh/identity/sponsor.py,sha256=93WaV2U3Db2mGNUHOWKg15uiuni2U4XZV_BfHqq7urw,6195
|
|
16
|
+
agentmesh/reward/__init__.py,sha256=Rf0f9NMN1_oEuNUjolzciifnj7navvsuGnF5-3ja4co,471
|
|
17
|
+
agentmesh/reward/engine.py,sha256=M2AiwcS2EN-AcgjPeyx-N3CNG-jlr15ybChVTr6xLEg,16528
|
|
18
|
+
agentmesh/reward/learning.py,sha256=vmEQFYYXDwQE551cOK5Ylnp8arIdClKr4wTxMTHikt0,9408
|
|
19
|
+
agentmesh/reward/scoring.py,sha256=13yUExcnC_oWlyO--mEfOx96EHUNQuqDeHqpVyLas5w,6269
|
|
20
|
+
agentmesh/trust/__init__.py,sha256=Xs0LwlFdX94rP1UPYzwi_ObaPAc2M-WgKw0vqGHU_Wg,489
|
|
21
|
+
agentmesh/trust/bridge.py,sha256=KDQW4nXTYmv2cqtvmFyguWknaNWPX7VYcbozSNgJkvI,12596
|
|
22
|
+
agentmesh/trust/capability.py,sha256=1Esvk43GeMcxWVt6ewkgNHARxAiVUwDuXp44E_3Fmok,9670
|
|
23
|
+
agentmesh/trust/handshake.py,sha256=na8obvrL1hJDy45H3NJaXSpiWOqouIG4GFNl5RLEf6Y,10988
|
|
24
|
+
agentmesh_platform-1.0.0a1.dist-info/METADATA,sha256=J7GjTxBAXKznYOMMOXzB4n00XN1T20PabiW0WxINtow,11623
|
|
25
|
+
agentmesh_platform-1.0.0a1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
26
|
+
agentmesh_platform-1.0.0a1.dist-info/entry_points.txt,sha256=uncSoKr8tqS-QEJJh7fIOvnGp2lnvgbulztvV_5t27E,54
|
|
27
|
+
agentmesh_platform-1.0.0a1.dist-info/licenses/LICENSE,sha256=sIkoGVzkakz4LseiSYurIlLFlmPKfOkCtqyDQOZh6Ww,10953
|
|
28
|
+
agentmesh_platform-1.0.0a1.dist-info/RECORD,,
|