Skip to content

Commit fe34387

Browse files
feat: update OpenClaw skill to current API, add OpenShell integration doc
- Fix 5 stale skill scripts to use current AgentMesh API: - trust-score.sh: RewardEngine -> RewardService - record-interaction.sh: record_success/failure -> record_task_success/failure - verify-identity.sh: from_did -> AgentDID.from_string + verify_signature - audit-log.sh: agentmesh.audit -> agentmesh.governance.audit (AuditLog) - generate-identity.sh: did:agentmesh: -> did:mesh: prefix - Update SKILL.md: v1.1.0, fix architecture diagram, update URLs - Add docs/integrations/openshell.md: complementary architecture guide showing OpenShell (sandbox isolation) + toolkit (governance intelligence) - Update openclaw-sidecar.md with OpenShell cross-reference - Add OpenShell integration link to README - Fix agent_identity snapshot for max_initial_trust_score field Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 01efa40 commit fe34387

File tree

10 files changed

+258
-30
lines changed

10 files changed

+258
-30
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ pip install agent-lightning # RL training governance
5555
- **[.NET SDK](packages/agent-governance-dotnet/README.md)** — NuGet package with full OWASP coverage
5656
- **[Tutorials](docs/tutorials/)** — Step-by-step guides for policy, identity, integrations, compliance, SRE, and sandboxing
5757
- **[Azure Deployment](docs/deployment/README.md)** — AKS, Azure AI Foundry, Container Apps, OpenClaw sidecar
58+
- **[NVIDIA OpenShell Integration](docs/integrations/openshell.md)** — Combine sandbox isolation with governance intelligence
5859
- **[OWASP Compliance](docs/OWASP-COMPLIANCE.md)** — Full ASI-01 through ASI-10 mapping
5960
- **[Architecture](docs/ARCHITECTURE.md)** — System design, security model, trust scoring
6061
- **[NIST RFI Mapping](docs/nist-rfi-mapping.md)** — Mapping to NIST AI Agent Security RFI (2026-00206)

docs/deployment/openclaw-sidecar.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
Deploy OpenClaw as an autonomous agent with the Agent Governance Toolkit as a sidecar on Azure Kubernetes Service (AKS) for runtime policy enforcement, identity verification, and SLO monitoring.
44

5+
> **New:** The toolkit now integrates with [NVIDIA OpenShell](../integrations/openshell.md) for combined sandbox isolation + governance intelligence. See the [OpenShell integration guide](../integrations/openshell.md) for the complementary architecture.
6+
57
> **See also:** [Deployment Overview](README.md) | [AKS Deployment](../../packages/agent-mesh/docs/deployment/azure.md) | [OpenClaw on ClawHub](https://clawhub.ai/microsoft/agentmesh-governance)
68
79
---

docs/integrations/openshell.md

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
# Integrating with NVIDIA OpenShell
2+
3+
Deploy the Agent Governance Toolkit as the governance layer inside (or alongside) [NVIDIA OpenShell](https://github.com/NVIDIA/OpenShell) sandboxes to combine **runtime isolation** with **governance intelligence**.
4+
5+
> **TL;DR** — OpenShell provides the *walls* (sandbox, network, filesystem policies). The toolkit provides the *brain* (identity, trust, policy decisions, audit). Together they form a complete agent security stack.
6+
7+
---
8+
9+
## Why Combine Them?
10+
11+
OpenShell and the Agent Governance Toolkit solve **different halves** of the agent security problem:
12+
13+
| Capability | OpenShell | Governance Toolkit |
14+
|---|:---:|:---:|
15+
| Container isolation |||
16+
| Filesystem policies |||
17+
| Network egress control |||
18+
| Process / syscall restrictions |||
19+
| Inference routing |||
20+
| Agent identity (Ed25519 DIDs) |||
21+
| Behavioral trust scoring |||
22+
| Policy engine (YAML + OPA + Cedar) |||
23+
| Authority resolution (reputation-gated delegation) |||
24+
| Tamper-evident Merkle audit chains |||
25+
| SLOs, circuit breakers, execution rings |||
26+
| Multi-agent governance |||
27+
28+
OpenShell asks: *"Is this network call allowed by sandbox policy?"*
29+
The toolkit asks: *"Should this agent be trusted to make this call at all?"*
30+
31+
Neither replaces the other — they're complementary layers in a defense-in-depth stack.
32+
33+
---
34+
35+
## Architecture
36+
37+
```
38+
┌──────────────────────────────────────────────────────────────────┐
39+
│ OpenShell Sandbox │
40+
│ │
41+
│ ┌────────────────────────┐ ┌────────────────────────────────┐ │
42+
│ │ AI Agent (Claude, │ │ Governance Toolkit (sidecar) │ │
43+
│ │ Codex, OpenCode, etc) │ │ │ │
44+
│ │ │ │ AgentIdentity — Ed25519 DIDs │ │
45+
│ │ Tool call ────────────────► PolicyEngine — YAML/OPA/Cedar│ │
46+
│ │ ◄────────────── RewardService — trust scoring │ │
47+
│ │ (allow / deny) │ │ AuditLog — Merkle chain │ │
48+
│ │ │ │ AuthorityResolver — delegation │ │
49+
│ └────────────────────────┘ └────────────────────────────────┘ │
50+
│ │
51+
│ ┌──────────────────────────────────────────────────────────────┐ │
52+
│ │ OpenShell Policy Engine │ │
53+
│ │ Filesystem ▸ Network ▸ Process ▸ Inference │ │
54+
│ └──────────────────────────────────────────────────────────────┘ │
55+
└──────────────────────────────────────────────────────────────────┘
56+
```
57+
58+
**Request flow:**
59+
60+
1. Agent issues a tool call (e.g., `shell:curl`, `file:write`)
61+
2. **Governance Toolkit** evaluates: identity verified? trust score above threshold? policy allows action? authority delegated?
62+
3. If governance approves → OpenShell's **sandbox policy engine** enforces runtime constraints (network egress, filesystem boundaries, process restrictions)
63+
4. Both layers log independently — governance writes to the Merkle audit chain, OpenShell writes to its own policy log
64+
5. If either layer denies → action is blocked
65+
66+
---
67+
68+
## Setup
69+
70+
### Option A: Governance Skill Inside the Sandbox
71+
72+
Install the toolkit as an [OpenClaw skill](../packages/agentmesh-integrations/openclaw-skill/) that the agent invokes before each action:
73+
74+
```bash
75+
# Inside the sandbox
76+
pip install agentmesh
77+
78+
# Use the skill scripts
79+
scripts/check-policy.sh --action "web_search" --tokens 1500 --policy policy.yaml
80+
scripts/trust-score.sh --agent "did:mesh:abc123"
81+
scripts/verify-identity.sh --did "did:mesh:abc123" --message "hello" --signature "base64sig"
82+
```
83+
84+
This approach is lightweight and works with any agent that supports OpenClaw skills.
85+
86+
### Option B: Governance Sidecar (Production)
87+
88+
Run the toolkit as a sidecar proxy that intercepts all tool calls transparently:
89+
90+
```yaml
91+
# openshell-governance-policy.yaml
92+
network:
93+
outbound:
94+
- match:
95+
host: "localhost"
96+
port: 8081
97+
action: allow # Allow agent → governance sidecar
98+
- match:
99+
host: "*.openai.com"
100+
action: allow # Allow approved LLM calls
101+
- action: deny # Block everything else
102+
103+
filesystem:
104+
read:
105+
- /workspace/**
106+
- /policies/**
107+
write:
108+
- /workspace/**
109+
- /var/log/governance/**
110+
```
111+
112+
```bash
113+
# Start the governance sidecar inside the sandbox
114+
python -m agentmesh.server --port 8081 --policy /policies/ &
115+
116+
# Create the sandbox with the policy
117+
openshell sandbox create \
118+
--policy openshell-governance-policy.yaml \
119+
-- claude
120+
```
121+
122+
See the full [OpenClaw sidecar deployment guide](../deployment/openclaw-sidecar.md) for AKS and Docker Compose configurations.
123+
124+
---
125+
126+
## Policy Layering Example
127+
128+
A single agent action passes through **two policy layers**:
129+
130+
```
131+
Agent: "I want to POST to https://api.github.com/repos/org/repo/issues"
132+
133+
Layer 1 — Governance Toolkit:
134+
✅ Agent identity verified (did:mesh:a1b2c3)
135+
✅ Trust score 0.82 > threshold 0.5
136+
✅ Policy allows "http:POST:api.github.com/*"
137+
✅ Authority: delegated by parent agent with scope "github:issues:create"
138+
→ ALLOW (logged to Merkle audit chain)
139+
140+
Layer 2 — OpenShell:
141+
✅ Network policy permits POST to api.github.com
142+
✅ Process policy permits curl binary
143+
→ ALLOW (logged to OpenShell policy log)
144+
145+
Result: Action executes
146+
```
147+
148+
If either layer denies:
149+
150+
```
151+
Agent: "I want to POST to https://169.254.169.254/metadata"
152+
153+
Layer 1 — Governance Toolkit:
154+
❌ Policy blocks "http:*:169.254.169.254/*" (cloud metadata endpoint)
155+
→ DENY (logged with violation reason)
156+
157+
Result: Action blocked before reaching OpenShell
158+
```
159+
160+
---
161+
162+
## OpenShell Policy + Governance Policy Mapping
163+
164+
| OpenShell Layer | Governance Toolkit Equivalent | How They Interact |
165+
|---|---|---|
166+
| `filesystem.read/write` | Capability policies (`file:read:*`, `file:write:*`) | Governance decides *who can*, OpenShell enforces *where* |
167+
| `network.outbound` | Capability policies (`http:GET:*`, `http:POST:*`) | Governance decides *what action*, OpenShell enforces *which endpoints* |
168+
| `process` | Blocked-tool policies, execution rings | Governance gates by trust level, OpenShell gates by syscall |
169+
| `inference` routing | N/A (complementary) | OpenShell routes LLM traffic; governance audits responses |
170+
| N/A | Identity, trust scoring, audit | Governance-only capabilities |
171+
172+
---
173+
174+
## Monitoring
175+
176+
When running both layers, you get two complementary telemetry streams:
177+
178+
**Governance Toolkit metrics** (Prometheus / OpenTelemetry):
179+
- `policy_decisions_total{result="allow|deny"}`
180+
- `trust_score_current{agent="did:mesh:..."}`
181+
- `audit_chain_entries_total`
182+
- `authority_resolutions_total{decision="allow|deny|narrowed"}`
183+
184+
**OpenShell metrics**:
185+
- Sandbox network egress logs
186+
- Filesystem access logs
187+
- Process execution logs
188+
- Inference routing logs
189+
190+
Both can feed into the same Grafana dashboard for a unified view. See the [Agent SRE monitoring guide](../../packages/agent-sre/README.md) for SLO configuration.
191+
192+
---
193+
194+
## FAQ
195+
196+
**Q: Do I need both?**
197+
No. Each works independently. But together they provide defense-in-depth: governance intelligence (who, what, why) plus runtime isolation (where, how).
198+
199+
**Q: Does the toolkit work with agents other than OpenClaw?**
200+
Yes. The toolkit is agent-agnostic — it works with any AI agent framework (LangChain, CrewAI, AutoGen, Semantic Kernel, etc.) on any cloud (AWS, GCP, Azure) or locally.
201+
202+
**Q: Does OpenShell replace the sidecar deployment?**
203+
OpenShell can *host* the sidecar. The governance sidecar runs inside or alongside the OpenShell sandbox. OpenShell provides the isolation boundary; the sidecar provides the governance logic.
204+
205+
**Q: What about NemoClaw?**
206+
[NemoClaw](https://nvidianews.nvidia.com/news/ai-agents) bundles OpenShell with NVIDIA Nemotron models. The governance toolkit works with NemoClaw the same way — it adds identity, trust, and audit capabilities on top of the NemoClaw runtime.
207+
208+
---
209+
210+
## Related
211+
212+
- [OpenClaw Skill](../../packages/agentmesh-integrations/openclaw-skill/) — Lightweight skill for OpenClaw agents
213+
- [OpenClaw Sidecar Deployment](../deployment/openclaw-sidecar.md) — AKS and Docker Compose guide
214+
- [NVIDIA OpenShell](https://github.com/NVIDIA/OpenShell) — Runtime sandbox for AI agents
215+
- [Architecture](../ARCHITECTURE.md) — Full toolkit architecture

packages/agent-mesh/tests/snapshots/agent_identity.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,6 @@
2121
"status": "active",
2222
"revocation_reason": null,
2323
"parent_did": null,
24-
"delegation_depth": 0
24+
"delegation_depth": 0,
25+
"max_initial_trust_score": null
2526
}

packages/agentmesh-integrations/openclaw-skill/SKILL.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ description: >
99
(5) user asks about agent safety, governance, compliance, or trust.
1010
Enterprise-grade: 1,600+ tests, merged into Dify (65K★), LlamaIndex (47K★),
1111
Microsoft Agent-Lightning (15K★).
12-
version: 1.0.0
12+
version: 1.1.0
1313
metadata:
1414
openclaw:
1515
requires:
1616
bins:
1717
- python3
1818
- pip
1919
emoji: "🛡️"
20-
homepage: https://github.com/imran-siddique/agentmesh-integrations/tree/master/openclaw-skill
20+
homepage: https://github.com/microsoft/agent-governance-toolkit/tree/main/packages/agentmesh-integrations/openclaw-skill
2121
---
2222

2323
# AgentMesh Governance — Trust & Policy for OpenClaw Agents
@@ -70,7 +70,7 @@ collaboration health.
7070
Verify an agent's Ed25519 cryptographic identity before trusting its output:
7171

7272
```bash
73-
scripts/verify-identity.sh --did "did:agentmesh:abc123" --message "hello" --signature "base64sig"
73+
scripts/verify-identity.sh --did "did:mesh:abc123" --message "hello" --signature "base64sig"
7474
```
7575

7676
Returns `verified: true/false`. Use when receiving data from another agent.
@@ -159,12 +159,12 @@ governance engine:
159159
```
160160
OpenClaw Agent → SKILL.md scripts → AgentMesh Engine
161161
├── GovernancePolicy (enforcement)
162-
├── TrustEngine (5-dimension scoring)
162+
├── RewardService (5-dimension scoring)
163163
├── AgentIdentity (Ed25519 DIDs)
164-
└── hash-chainAuditChain (tamper-evident logs)
164+
└── AuditLog (tamper-evident Merkle chains)
165165
```
166166

167-
Part of the [Agent Ecosystem](https://imran-siddique.github.io):
168-
[AgentMesh](https://github.com/imran-siddique/agent-mesh) ·
169-
[Agent OS](https://github.com/imran-siddique/agent-os) ·
170-
[Agent SRE](https://github.com/imran-siddique/agent-sre)
167+
Part of the [Agent Governance Toolkit](https://github.com/microsoft/agent-governance-toolkit):
168+
[AgentMesh](https://github.com/microsoft/agent-governance-toolkit/tree/main/packages/agent-mesh) ·
169+
[Agent OS](https://github.com/microsoft/agent-governance-toolkit/tree/main/packages/agent-os) ·
170+
[Agent SRE](https://github.com/microsoft/agent-governance-toolkit/tree/main/packages/agent-sre)

packages/agentmesh-integrations/openclaw-skill/scripts/audit-log.sh

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,16 @@ done
1515
python3 -c "
1616
import json
1717
try:
18-
from agentmesh.audit import MerkleAuditChain
19-
chain = MerkleAuditChain()
20-
entries = chain.get_entries(agent='$AGENT' or None, last=int('$LAST'))
18+
from agentmesh.governance.audit import AuditLog
19+
audit_log = AuditLog()
20+
agent_filter = '$AGENT' or None
21+
if agent_filter:
22+
entries = audit_log.get_entries_for_agent(agent_did=agent_filter, limit=int('$LAST'))
23+
else:
24+
entries = audit_log.query(limit=int('$LAST'))
2125
if '$VERIFY' == 'true':
22-
valid = chain.verify_integrity()
23-
print(json.dumps({'integrity': 'valid' if valid else 'TAMPERED', 'entries': len(entries)}, indent=2))
26+
valid, error = audit_log.verify_integrity()
27+
print(json.dumps({'integrity': 'valid' if valid else 'TAMPERED', 'error': error, 'entries': len(entries)}, indent=2))
2428
else:
2529
print(json.dumps([e.to_dict() for e in entries], indent=2))
2630
except ImportError:

packages/agentmesh-integrations/openclaw-skill/scripts/generate-identity.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat,
1919
key = Ed25519PrivateKey.generate()
2020
pub = key.public_key()
2121
pub_bytes = pub.public_bytes(Encoding.Raw, PublicFormat.Raw)
22-
did = 'did:agentmesh:' + hashlib.sha256(pub_bytes).hexdigest()[:16]
22+
did = 'did:mesh:' + hashlib.sha256(pub_bytes).hexdigest()[:16]
2323
2424
caps = [c.strip() for c in '${CAPABILITIES}'.split(',') if c.strip()]
2525

packages/agentmesh-integrations/openclaw-skill/scripts/record-interaction.sh

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ done
1515
python3 -c "
1616
import json, datetime
1717
try:
18-
from agentmesh.trust import RewardEngine
19-
engine = RewardEngine()
18+
from agentmesh.services import RewardService
19+
service = RewardService()
2020
if '$OUTCOME' == 'success':
21-
engine.record_success('$AGENT')
21+
service.record_task_success('$AGENT', task_id='openclaw-interaction')
2222
else:
23-
engine.record_failure('$AGENT', severity=float('$SEVERITY'))
24-
score = engine.get_score('$AGENT')
25-
print(json.dumps(score, indent=2))
23+
service.record_task_failure('$AGENT', reason='severity=$SEVERITY')
24+
score = service.get_score('$AGENT')
25+
print(json.dumps(score.to_dict() if hasattr(score, 'to_dict') else score, indent=2))
2626
except ImportError:
2727
delta = 0.01 if '$OUTCOME' == 'success' else -float('$SEVERITY')
2828
result = {

packages/agentmesh-integrations/openclaw-skill/scripts/trust-score.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ done
1313
python3 -c "
1414
import json
1515
try:
16-
from agentmesh.trust import RewardEngine
17-
engine = RewardEngine()
18-
score = engine.get_score('$AGENT')
19-
print(json.dumps(score, indent=2))
16+
from agentmesh.services import RewardService
17+
service = RewardService()
18+
score = service.get_score('$AGENT')
19+
print(json.dumps(score.to_dict() if hasattr(score, 'to_dict') else score, indent=2))
2020
except ImportError:
2121
# Standalone mode — return baseline trust info
2222
result = {

packages/agentmesh-integrations/openclaw-skill/scripts/verify-identity.sh

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,15 @@ done
1515
python3 -c "
1616
import json
1717
try:
18-
from agentmesh.identity import AgentIdentity
19-
identity = AgentIdentity.from_did('$DID')
20-
verified = identity.verify(b'$MESSAGE', '$SIGNATURE')
21-
print(json.dumps({'did': '$DID', 'verified': verified}, indent=2))
18+
from agentmesh.identity import AgentIdentity, AgentDID, IdentityRegistry
19+
parsed = AgentDID.from_string('$DID')
20+
registry = IdentityRegistry()
21+
identity = registry.get(parsed)
22+
if identity is None:
23+
print(json.dumps({'did': '$DID', 'verified': False, 'error': 'DID not found in registry'}, indent=2))
24+
else:
25+
verified = identity.verify_signature(b'$MESSAGE', '$SIGNATURE')
26+
print(json.dumps({'did': '$DID', 'verified': verified}, indent=2))
2227
except ImportError:
2328
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
2429
import base64

0 commit comments

Comments
 (0)