feat: sb-runtime governance skill (signed decision receipts, nono-composable)#1203
Conversation
Adds a new AgentMesh integration under packages/agentmesh-integrations/sb-runtime-skill/ parallel to the existing openshell-skill. Same policy contract; adds Ed25519-signed decision receipts in the Veritas Acta receipt format (draft-farley-acta-signed-receipts-02). Three supported deployment shapes, all recording the sandbox layer in the signed payload for auditor visibility: - sandbox_backend=sb_runtime_builtin, ring=3: one binary owns Cedar + Landlock/seccomp + receipts (default). - sandbox_backend=nono, ring=2: nono wraps the agent process and owns the sandbox; this skill contributes only Cedar + receipts. Recommended Linux composition per docs/integrations/sb-runtime.md. - sandbox_backend=openshell, ring=2: OpenShell owns the container boundary; this skill contributes Cedar + receipts. Receipts verify offline against @veritasacta/verify without dependency on this skill, sb-runtime, or AgentMesh. Policy digest (sha256 of the canonicalized ruleset) is pinned into every receipt; chain linkage via previousReceiptHash across successive decisions. Tests: 23 passing, covering policy contract parity with openshell-skill (9), receipt signing / verification / tampering (6), sandbox-backend recording (4), policy digest determinism (2), and signer key loading (2). Part of PR microsoft#1202 (integration doc) + this shim + a forthcoming worked example.
|
Welcome to the Agent Governance Toolkit! Thanks for your first pull request. |
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review Summary
This PR introduces the sb-runtime-skill package, a governance skill for policy evaluation and Ed25519-signed decision receipts in the Veritas Acta format. The implementation appears well-aligned with the stated goals and specifications, including policy contract parity with openshell-skill, cryptographic receipt signing, sandbox backend recording, and chain linkage. However, several critical security issues, potential breaking changes, and areas for improvement have been identified.
🔴 CRITICAL: Security Issues
-
Receipt Signing Vulnerability:
- The
sign_receiptfunction does not validate the structure of the payload before signing. This could allow an attacker to inject malicious or malformed data into the receipt payload, which would then be signed and appear valid to verifiers. - Recommendation: Implement strict validation of the payload structure before signing. Ensure all required fields are present and conform to expected types.
- The
-
Key Management:
- The
Signer.generate()method creates ephemeral keys but does not provide a secure mechanism for long-term key storage or rotation. This could lead to compromised operator keys being used indefinitely. - Recommendation: Introduce key rotation and secure storage mechanisms, such as integration with a hardware security module (HSM) or a secure key management service.
- The
-
Sandbox Escape Risk:
- The
SandboxBackend.NONEoption allows execution without any sandboxing. While this is marked as suitable for test harnesses, it could be misused in production environments, exposing the system to potential security risks. - Recommendation: Add explicit warnings in the documentation and code comments about the risks of using
SandboxBackend.NONEin production. Consider adding runtime checks to prevent accidental use.
- The
-
Receipt Verification:
- The
verify_receiptfunction returnsFalsefor invalid signatures but does not provide detailed error messages for debugging or auditing purposes. This could hinder incident response and forensic analysis. - Recommendation: Log detailed error messages when verification fails, including the reason (e.g., invalid signature, malformed envelope).
- The
🟡 WARNING: Potential Breaking Changes
-
Python Version Requirement:
- The package requires Python
>=3.10. This may break compatibility for users on older Python versions (e.g., 3.9), which are still supported by the repository. - Recommendation: Consider lowering the requirement to
>=3.9or explicitly document the rationale for requiring Python 3.10.
- The package requires Python
-
Policy Directory Loading:
- The
load_policiesmethod clears existing rules before loading new ones. This could lead to unexpected behavior if the method is called multiple times during runtime. - Recommendation: Add a parameter to control whether existing rules should be cleared or merged with new ones.
- The
💡 Suggestions for Improvement
-
Thread Safety:
- The
GovernanceSkillclass maintains mutable state (e.g.,_previous_receipt_hash,_trust_scores,_audit_log) that could lead to race conditions in concurrent environments. - Recommendation: Use thread-safe data structures (e.g.,
threading.Lockorconcurrent.futures) to protect shared state.
- The
-
Type Safety:
- While the code uses type hints, there is no enforcement of schema validation for the
PolicyDecisionor receipt payloads. - Recommendation: Use Pydantic models for strict validation of
PolicyDecisionand receipt payloads.
- While the code uses type hints, there is no enforcement of schema validation for the
-
CLI Usability:
- The CLI does not provide clear error messages for invalid input (e.g., malformed JSON in
--context). - Recommendation: Add input validation and user-friendly error messages for CLI arguments.
- The CLI does not provide clear error messages for invalid input (e.g., malformed JSON in
-
Documentation:
- The README does not explicitly warn about the risks of using
SandboxBackend.NONEin production. - Recommendation: Add a dedicated "Security Considerations" section to the README.
- The README does not explicitly warn about the risks of using
-
Backward Compatibility:
- The
sb-runtime-skillpackage introduces new functionality but does not provide migration guidance for users transitioning fromopenshell-skill. - Recommendation: Include a migration guide in the documentation.
- The
-
Testing Coverage:
- While the PR includes 23 tests, there is no mention of edge cases, such as malformed policies, invalid receipt payloads, or corrupted keys.
- Recommendation: Add tests for edge cases and failure scenarios.
Conclusion
This PR introduces valuable functionality for policy evaluation and signed decision receipts, but it has several critical security vulnerabilities and potential breaking changes that need to be addressed before merging. The recommendations provided should be implemented to ensure the robustness, security, and backward compatibility of the sb-runtime-skill package.
🤖 AI Agent: security-scanner — Security Findings for Pull Request: feat: sb-runtime governance skillSecurity Findings for Pull Request: feat: sb-runtime governance skill
SummaryThis pull request introduces significant functionality that enhances the governance capabilities of the toolkit. However, it also introduces several critical security concerns that must be addressed to ensure the integrity and security of the entire system. Immediate attention should be given to the critical findings, particularly around input validation and credential exposure, to mitigate potential risks to downstream users. |
imran-siddique
left a comment
There was a problem hiding this comment.
Good work — correctly placed under \packages/agentmesh-integrations/\ as an extension (not core). The skill follows the same contract as openshell-skill, receipts implementation looks solid, and tests are included. Merging.
…pt portability) PR 3 in the three-PR sequence proposed on microsoft#748 (after microsoft#1202 integration doc and microsoft#1203 provider shim, both merged). Demonstrates the architectural claim of the sb-runtime integration: a single Cedar policy produces semantically-equivalent signed receipts regardless of which sandbox layer wraps the agent process, and the sandbox_backend field is covered by the Ed25519 signature (not sidecar metadata). The demo runs six governed actions (three allowed, three denied) through three sandbox-backend configurations using the same Cedar policy and the same operator key: 1. standalone sandbox_backend=sb_runtime_builtin ring=3 2. nono sandbox_backend=nono ring=2 3. openshell sandbox_backend=openshell ring=2 Then: - Cross-verifies all 18 receipts against the single operator public key (zero dependency on the sb_runtime_agentmesh skill at verify time; matches what @veritasacta/verify would do offline). - Demonstrates tamper-evidence by flipping sandbox_backend on a receipt and confirming verification fails (the field is inside the signature scope). - Confirms chain linkage: receipt[1].previousReceiptHash equals sha256(canonical(receipt[0])). - Writes the receipts + operator public key to disk under examples/sb-runtime-governed/receipts/ (gitignored) so the output is inspectable and re-verifiable with external tooling. Files: - README.md: walkthrough with expected output - getting_started.py: ~280-line demo, three scenarios + verification - policies/sandbox-policy.yaml: shared across all three scenarios - .gitignore: excludes receipts/ and __pycache__ No changes outside examples/sb-runtime-governed/. Depends on: - pyyaml>=6,<7 (same as openshell-skill) - cryptography>=41 (for Ed25519 + JCS canonicalization) Both are declared in the sb-runtime-skill pyproject.toml (microsoft#1203). Cc @imran-siddique (closing the three-PR sequence as committed), @lukehinds (the nono scenario uses sandbox_backend="nono" matching the composition pattern documented in microsoft#1202; happy to match nono's native CLI flag conventions when the nono Python library is wired in for actual runtime enforcement).
… 3 of 3 from #748) (#1205) * examples: add sb-runtime-governed worked example (multi-backend receipt portability) PR 3 in the three-PR sequence proposed on #748 (after #1202 integration doc and #1203 provider shim, both merged). Demonstrates the architectural claim of the sb-runtime integration: a single Cedar policy produces semantically-equivalent signed receipts regardless of which sandbox layer wraps the agent process, and the sandbox_backend field is covered by the Ed25519 signature (not sidecar metadata). The demo runs six governed actions (three allowed, three denied) through three sandbox-backend configurations using the same Cedar policy and the same operator key: 1. standalone sandbox_backend=sb_runtime_builtin ring=3 2. nono sandbox_backend=nono ring=2 3. openshell sandbox_backend=openshell ring=2 Then: - Cross-verifies all 18 receipts against the single operator public key (zero dependency on the sb_runtime_agentmesh skill at verify time; matches what @veritasacta/verify would do offline). - Demonstrates tamper-evidence by flipping sandbox_backend on a receipt and confirming verification fails (the field is inside the signature scope). - Confirms chain linkage: receipt[1].previousReceiptHash equals sha256(canonical(receipt[0])). - Writes the receipts + operator public key to disk under examples/sb-runtime-governed/receipts/ (gitignored) so the output is inspectable and re-verifiable with external tooling. Files: - README.md: walkthrough with expected output - getting_started.py: ~280-line demo, three scenarios + verification - policies/sandbox-policy.yaml: shared across all three scenarios - .gitignore: excludes receipts/ and __pycache__ No changes outside examples/sb-runtime-governed/. Depends on: - pyyaml>=6,<7 (same as openshell-skill) - cryptography>=41 (for Ed25519 + JCS canonicalization) Both are declared in the sb-runtime-skill pyproject.toml (#1203). Cc @imran-siddique (closing the three-PR sequence as committed), @lukehinds (the nono scenario uses sandbox_backend="nono" matching the composition pattern documented in #1202; happy to match nono's native CLI flag conventions when the nono Python library is wired in for actual runtime enforcement). * fix: use Microsoft copyright header per imran-siddique review Per @imran-siddique in #1205, swap the Tom Farley (ScopeBlind) header for the repo's standard Microsoft Corporation / MIT License header. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: tommylauren <tfarley@utexas.edu> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… 3 of 3 from microsoft#748) (microsoft#1205) * examples: add sb-runtime-governed worked example (multi-backend receipt portability) PR 3 in the three-PR sequence proposed on microsoft#748 (after microsoft#1202 integration doc and microsoft#1203 provider shim, both merged). Demonstrates the architectural claim of the sb-runtime integration: a single Cedar policy produces semantically-equivalent signed receipts regardless of which sandbox layer wraps the agent process, and the sandbox_backend field is covered by the Ed25519 signature (not sidecar metadata). The demo runs six governed actions (three allowed, three denied) through three sandbox-backend configurations using the same Cedar policy and the same operator key: 1. standalone sandbox_backend=sb_runtime_builtin ring=3 2. nono sandbox_backend=nono ring=2 3. openshell sandbox_backend=openshell ring=2 Then: - Cross-verifies all 18 receipts against the single operator public key (zero dependency on the sb_runtime_agentmesh skill at verify time; matches what @veritasacta/verify would do offline). - Demonstrates tamper-evidence by flipping sandbox_backend on a receipt and confirming verification fails (the field is inside the signature scope). - Confirms chain linkage: receipt[1].previousReceiptHash equals sha256(canonical(receipt[0])). - Writes the receipts + operator public key to disk under examples/sb-runtime-governed/receipts/ (gitignored) so the output is inspectable and re-verifiable with external tooling. Files: - README.md: walkthrough with expected output - getting_started.py: ~280-line demo, three scenarios + verification - policies/sandbox-policy.yaml: shared across all three scenarios - .gitignore: excludes receipts/ and __pycache__ No changes outside examples/sb-runtime-governed/. Depends on: - pyyaml>=6,<7 (same as openshell-skill) - cryptography>=41 (for Ed25519 + JCS canonicalization) Both are declared in the sb-runtime-skill pyproject.toml (microsoft#1203). Cc @imran-siddique (closing the three-PR sequence as committed), @lukehinds (the nono scenario uses sandbox_backend="nono" matching the composition pattern documented in microsoft#1202; happy to match nono's native CLI flag conventions when the nono Python library is wired in for actual runtime enforcement). * fix: use Microsoft copyright header per imran-siddique review Per @imran-siddique in microsoft#1205, swap the Tom Farley (ScopeBlind) header for the repo's standard Microsoft Corporation / MIT License header. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: tommylauren <tfarley@utexas.edu> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
PR 2 of the three-PR sequence discussed on #748 and #1202. Adds a drop-in governance skill under
packages/agentmesh-integrations/sb-runtime-skill/that mirrors the existingopenshell-skillcontract and layers Ed25519-signed decision receipts in the Veritas Acta receipt format on top.Builds on:
What's in the shim
openshell-skill. Same YAML schema, samecheck_policy(action, context)surface, same trust-score and audit-log methods. An operator swappingopenshell_agentmeshforsb_runtime_agentmeshdoes not need to change call sites.check_policycall returns aPolicyDecisionwith areceiptfield: a JCS-canonical, Ed25519-signed envelope that verifies offline against@veritasacta/verifywith no dependency on this shim, sb-runtime, or AgentMesh.previousReceiptHash.sha256:<hex>of the active canonicalized ruleset.sandbox_backendis one ofsb_runtime_builtin,nono(Ring 2 composition per docs: sb-runtime integration guide (a Veritas Acta receipt format implementation) #1202),openshell(Ring 2 container composition), ornone. Auditors see which layer wrapped the process because it is covered by the signature.sb-runtime-governance).check-policy(with--receipts-dirfor on-disk persistence),verify,trust-score, andpublic-keysubcommands.Tests
23 passing under
pytest tests/:openshell-skill(9): allow, deny, default-deny, trust, audit, load, missing, priority.sign=Falseopt-out.No changes outside
packages/agentmesh-integrations/sb-runtime-skill/.Spec alignment
Notes
pyyaml>=6,<7(same as openshell-skill) +cryptography>=41,<47for Ed25519.examples/sb-runtime-governed/and exercise both standalone and nono-composed configurations.Cc @imran-siddique (per the three-PR sequence on #1202), @lukehinds (the nono composition path is first-class here; happy to adjust the expected flag layout or capability-file conventions if anything would align better with nono's defaults).