examples: sb-runtime-governed — multi-backend receipt portability (PR 3 of 3 from #748)#1205
Conversation
…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).
|
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 a worked example demonstrating the architectural claim of sb-runtime integration: multi-backend receipt portability with signed receipts that are semantically equivalent across different sandbox layers. The example is well-documented, self-contained, and adheres to the repository's conventions. However, there are areas that require attention to ensure security, correctness, and backward compatibility.
🔴 CRITICAL: Security Issues
-
Sandbox Escape Vectors
- The
sandbox_backendfield is included in the signed payload, which is good for tamper-evidence. However, the example does not validate whether the sandbox backend actually enforces the expected security guarantees. For example, thenonobackend is currently a placeholder and does not enforce runtime sandboxing. This could lead to a false sense of security if operators rely solely on the receipt without verifying the actual sandbox behavior. - Actionable: Add runtime checks or attestations to ensure the sandbox backend is actively enforcing the expected security policies. Consider integrating runtime integrity checks or attestation mechanisms.
- The
-
Cryptographic Operations
- The
Signerclass is used for signing receipts, but the implementation details ofSignerare not included in this PR. IfSignerdoes not use a secure Ed25519 implementation or has vulnerabilities in its key management, the entire receipt verification process could be compromised. - Actionable: Audit the
Signerimplementation insb-runtime-skillto ensure it uses a secure cryptographic library (e.g.,cryptography) and follows best practices for key management.
- The
-
Tampering Demonstration
- While the tampering demonstration proves that the
sandbox_backendfield is inside the signature scope, it does not address potential replay attacks. An attacker could replay a valid receipt from a weaker sandbox backend (none) to bypass security checks. - Actionable: Include a nonce or timestamp in the receipt payload to prevent replay attacks.
- While the tampering demonstration proves that the
🟡 WARNING: Potential Breaking Changes
-
Policy Format
- The policy format in
sandbox-policy.yamluses a custom schema (governance.toolkit/v1). If this schema changes in the future, it could break backward compatibility for this example. - Actionable: Document the schema version explicitly in the example and provide migration instructions for future schema updates.
- The policy format in
-
Dependency on
sb-runtime-skill- This example depends on the
sb-runtime-skillpackage, which is imported directly from the repository. If the package structure changes, the example will break. - Actionable: Pin the
sb-runtime-skillversion in the example's README and test plan.
- This example depends on the
💡 Suggestions for Improvement
-
Thread Safety
- The example does not address thread safety in concurrent agent execution. While this is not directly relevant to the example, it is critical for real-world deployments where multiple agents may execute policies concurrently.
- Actionable: Add a note in the README about thread safety considerations and recommend using thread-safe components in production.
-
Type Safety
- The example does not use Pydantic models for receipt validation. This could lead to runtime errors if the receipt structure changes or contains unexpected fields.
- Actionable: Use Pydantic models to validate receipt structures before signing and verifying.
-
OWASP Agentic Top 10 Compliance
- The example does not explicitly address OWASP Agentic Top 10 risks, such as insufficient logging or insecure communication.
- Actionable: Add logging for all critical operations (e.g., receipt signing, verification, tampering detection) and ensure that all communication is encrypted.
-
Documentation
- The README is comprehensive but could benefit from a visual diagram illustrating the receipt flow across sandbox layers.
- Actionable: Add a diagram showing the receipt lifecycle, including signing, verification, and tamper-evidence.
-
Testing
- The test plan does not include edge cases, such as invalid policies, malformed receipts, or corrupted operator keys.
- Actionable: Extend the test plan to include these edge cases and ensure the example handles them gracefully.
Final Recommendation
- Address the 🔴 CRITICAL issues before merging to ensure the example does not introduce security vulnerabilities.
- Resolve the 🟡 WARNING items to maintain backward compatibility and robustness.
- Implement the 💡 SUGGESTIONS to improve the example's usability, security, and compliance.
Once these issues are addressed, the example will be a valuable addition to the repository, demonstrating the architectural claim of sb-runtime integration effectively.
🤖 AI Agent: security-scanner — Security Review for PR: `examples: sb-runtime-governed — multi-backend receipt portability`Security Review for PR:
|
| Category | Risk | Description |
|---|---|---|
| Prompt Injection Defense | 🔵 LOW | No user-provided input; no immediate risk. |
| Policy Engine Circumvention | 🟠 HIGH | nono sandbox is a placeholder and does not enforce runtime isolation. |
| Trust Chain Weaknesses | 🔵 LOW | Trust chain appears robust; no immediate issues. |
| Credential Exposure | 🔵 LOW | No sensitive credentials are exposed. |
| Sandbox Escape | 🟠 HIGH | Lack of runtime enforcement in nono sandbox could allow sandbox escape. |
| Deserialization Attacks | 🟡 MEDIUM | Use of pyyaml introduces potential risks; switch to yaml.safe_load. |
| Race Conditions | 🔵 LOW | No evidence of TOCTOU vulnerabilities. |
| Supply Chain | 🟡 MEDIUM | Dependencies should be pinned to specific versions to mitigate supply chain risks. |
Recommendations
-
Address
nonoSandbox Placeholder:- Clearly document the lack of runtime enforcement in the
nonosandbox. - Implement runtime sandboxing for
nonoor remove it from the example until it is functional.
- Clearly document the lack of runtime enforcement in the
-
Secure YAML Deserialization:
- Replace
yaml.loadwithyaml.safe_loadin the policy loading code to prevent deserialization attacks.
- Replace
-
Pin Dependencies:
- Pin
pyyamlandcryptographyto specific versions in the dependency configuration files. - Regularly audit dependencies for vulnerabilities.
- Pin
-
Enhance Sandbox Testing:
- Add automated tests to validate the isolation properties of each sandbox backend to ensure they meet security expectations.
-
Monitor for Future Risks:
- If user input is introduced in future iterations, ensure robust input validation and sanitization to prevent prompt injection attacks.
Final Rating: 🟠 HIGH
The primary concerns are the lack of runtime enforcement in the nono sandbox and the potential for deserialization attacks via pyyaml. Addressing these issues should be prioritized to ensure the security and reliability of the example.
imran-siddique
left a comment
There was a problem hiding this comment.
Nice work — this cleanly finishes the #748 series. One required change before merge:
License header in \getting_started.py\ — per repo convention, all new source files must use:
\\python
Copyright (c) Microsoft Corporation.
Licensed under the MIT License.
\\
Currently has # Copyright (c) 2026 Tom Farley (ScopeBlind). Please update to the Microsoft header. Everything else looks good — will merge once that's fixed.
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>
|
@imran-siddique fixed in ac669de, thanks. |
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review Summary
This pull request introduces a worked example demonstrating the portability of signed receipts across multiple sandbox backends (sb_runtime_builtin, nono, and openshell) using the same Cedar policy. The example validates the architectural claim that the sandbox_backend field is included in the signature scope, ensuring tamper-evidence and consistent verification across all backends. The PR is well-documented, includes a comprehensive test plan, and does not introduce changes outside the examples/sb-runtime-governed/ directory.
Below is a detailed review of the PR, focusing on the specified areas of concern.
🔴 CRITICAL: Security Issues
-
Receipt Tampering Demonstration:
- The
demonstrate_tamperingfunction modifies thesandbox_backendfield in a receipt and verifies that the tampered receipt fails verification. While this is a useful demonstration, the code does not explicitly validate that thesandbox_backendfield is always included in the signature scope. If this behavior is accidentally changed in the future, it could lead to a security vulnerability where thesandbox_backendfield is no longer protected by the signature. - Recommendation: Add a unit test in the
sb_runtime_agentmesh.receiptsmodule to explicitly verify that thesandbox_backendfield is always included in the signature scope. This test should fail if the field is ever excluded from the signature.
- The
-
Receipt Chain Linkage:
- The
demonstrate_chain_linkagefunction verifies that thepreviousReceiptHashfield matches the hash of the previous receipt. However, there is no explicit test to ensure that thepreviousReceiptHashfield is always included in the signed payload. - Recommendation: Add a unit test in the
sb_runtime_agentmesh.receiptsmodule to ensure that thepreviousReceiptHashfield is always included in the signature scope. This will prevent potential tampering with the receipt chain.
- The
-
Key Management:
- The
Signerclass generates a new operator key for each run of the example. While this is acceptable for a demo, it does not reflect real-world usage where operator keys are long-lived and securely stored. - Recommendation: Add a note in the
README.mdfile emphasizing that in production, operator keys should be securely generated and stored using a hardware security module (HSM) or equivalent secure key management solution.
- The
🟡 WARNING: Potential Breaking Changes
No breaking changes were identified in this PR. The changes are confined to the examples/sb-runtime-governed/ directory and do not affect the core functionality or public API of the library.
💡 Suggestions for Improvement
-
Code Readability:
- The
run_scenariofunction could benefit from additional comments explaining the purpose of theGovernanceSkillinitialization parameters, especially for developers unfamiliar with thesb_runtime_agentmeshmodule. - Consider adding type hints for all function parameters and return types for better readability and type safety.
- The
-
Error Handling:
- The
tryblock for importingsb_runtime_agentmesh.skillandsb_runtime_agentmesh.receiptsraises aSystemExiton failure. While this is acceptable for a demo, it would be better to provide a more descriptive error message and suggest potential resolutions. - Example:
except ImportError as exc: print( f"Error: Unable to import sb-runtime-skill. Please ensure the package is installed " f"and the repository layout is intact. Run:\n\n" f" pip install -e packages/agentmesh-integrations/sb-runtime-skill/\n\n" f"Details: {exc}" ) sys.exit(1)
- The
-
Policy Validation:
- The
sandbox-policy.yamlfile is well-structured, but there is no validation step in the example to ensure the policy conforms to the expected schema. - Recommendation: Use a Pydantic model or a JSON schema to validate the policy file before loading it into the
GovernanceSkill. This will help catch any errors in the policy definition early.
- The
-
Thread Safety:
- The
GovernanceSkillclass is instantiated multiple times in therun_scenariofunction. If this class is used in a multithreaded context in the future, ensure that it is thread-safe, especially when accessing shared resources like thesigner.
- The
-
Documentation:
- The
README.mdfile is comprehensive, but it could benefit from a section explaining how to interpret thesandbox_backendfield and its significance in the context of security and auditability. - Add a note about the importance of using a secure random number generator for key generation in the
Signerclass.
- The
-
Test Coverage:
- While the example includes a test plan, it does not integrate with the repository's
pytesttest suite. Consider adding automated tests to ensure the example's functionality is verified during CI/CD runs.
- While the example includes a test plan, it does not integrate with the repository's
Final Assessment
The PR is well-structured and provides a valuable example of the sb-runtime integration's capabilities. However, the following critical issues must be addressed before merging:
- Add explicit tests to ensure the
sandbox_backendandpreviousReceiptHashfields are always included in the signature scope. - Emphasize secure key management practices in the documentation.
Once these issues are resolved, the PR can be safely merged. The suggested improvements can be addressed in subsequent iterations to further enhance the quality and maintainability of the code.
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review Summary
This pull request introduces a worked example demonstrating the portability of signed receipts across multiple sandbox backends using the sb-runtime integration. The example is well-documented, adheres to the architectural claims, and provides a clear demonstration of tamper-evidence, chain linkage, and cross-verification of receipts. The code is structured and aligns with the existing patterns in the repository.
Below is the detailed review, including critical issues, warnings, and suggestions.
🔴 CRITICAL
-
Tamper Test Validation
- The tamper test in
demonstrate_tamperingrelies on flipping thesandbox_backendfield and verifying the signature. While the test demonstrates that the field is included in the signature scope, it does not test other potential tampering scenarios, such as modifying other fields in the payload or the signature itself. This could lead to a false sense of security.- Action: Extend the tamper test to include other fields in the payload (e.g.,
decision,policy_digest,ring) and the signature itself. Ensure that any modification invalidates the receipt.
- Action: Extend the tamper test to include other fields in the payload (e.g.,
- The tamper test in
-
Thread Safety of
Signer- The
Signerclass is used to sign receipts, but its thread safety is not explicitly guaranteed. If this example is extended to a multi-threaded environment, concurrent access to theSignerinstance could lead to race conditions or corrupted signatures.- Action: Ensure that the
Signerclass is thread-safe or document that it should not be shared across threads.
- Action: Ensure that the
- The
-
Receipt Verification
- The
verify_receiptfunction is used to validate receipts, but there is no explicit check for the integrity of thepreviousReceiptHashfield during verification. This could allow an attacker to tamper with the chain linkage without detection.- Action: Ensure that the receipt verification process includes a check for the integrity of the
previousReceiptHashfield.
- Action: Ensure that the receipt verification process includes a check for the integrity of the
- The
🟡 WARNING
-
Backward Compatibility
- While this PR does not introduce changes to the core library, it relies on the
sb-runtime-skillpackage introduced in #1203. If there are any breaking changes in thesb-runtime-skillpackage, it could affect this example.- Action: Ensure that the
sb-runtime-skillpackage maintains backward compatibility or document the required version explicitly in the example's README.
- Action: Ensure that the
- While this PR does not introduce changes to the core library, it relies on the
-
Policy File Compatibility
- The
sandbox-policy.yamlfile uses specific syntax and fields (e.g.,field,operator,value). If the policy engine's schema changes in the future, this example may break.- Action: Add a note in the README to specify the version of the policy engine that this example is compatible with.
- The
💡 SUGGESTIONS
-
Improved Documentation
- The README is comprehensive, but it could benefit from a brief explanation of the
sandbox_backendfield and its significance in the context of the architectural claim.- Action: Add a short section in the README explaining the
sandbox_backendfield and why it is critical for auditability and security.
- Action: Add a short section in the README explaining the
- The README is comprehensive, but it could benefit from a brief explanation of the
-
Error Handling
- The
run_scenariofunction usesassertstatements to check for the presence of a receipt. While this is acceptable for a demo, it might be better to raise a more descriptive exception or log an error message.- Action: Replace
assertwith explicit error handling and logging to improve clarity and maintainability.
- Action: Replace
- The
-
Policy Validation
- The
sandbox-policy.yamlfile is critical to the example. However, there is no validation step to ensure the policy adheres to the expected schema.- Action: Add a validation step for the policy file using the policy engine's schema before running the scenarios.
- The
-
Test Coverage
- While the example includes a test plan, it does not integrate with the repository's
pytestframework.- Action: Create a pytest-compatible test suite for this example to ensure it is automatically tested in the CI/CD pipeline.
- While the example includes a test plan, it does not integrate with the repository's
-
Receipt Format Documentation
- The
draft-farley-acta-signed-receipts-02format is referenced but not explained in detail. This could be a barrier for new users.- Action: Include a brief summary of the receipt format in the README or link to a detailed explanation.
- The
-
Sandbox Backend Abstraction
- The
SandboxBackendenum is used to specify the sandbox layer. If new backends are added in the future, this example will need to be updated.- Action: Consider abstracting the sandbox backend configuration to make it easier to extend the example with new backends.
- The
-
Logging
- The example uses
printstatements for output. While this is acceptable for a demo, using a logging library would provide more flexibility and consistency.- Action: Replace
printstatements with Python'sloggingmodule to allow configurable log levels and better integration with other tools.
- Action: Replace
- The example uses
-
Dependency Management
- The example relies on the
sb-runtime-skillpackage being installed in editable mode. This could lead to issues if the package is not installed correctly.- Action: Add a check at the start of the script to verify that the
sb-runtime-skillpackage is installed and importable.
- Action: Add a check at the start of the script to verify that the
- The example relies on the
Final Assessment
The PR is well-constructed and demonstrates the architectural claims effectively. However, there are critical areas that need to be addressed to ensure the example is secure, robust, and extensible. Once the identified issues are resolved, this PR will be a valuable addition to the repository.
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review Summary
This PR introduces a worked example demonstrating the portability of signed receipts across multiple sandbox backends (sb_runtime_builtin, nono, and openshell). The example validates the architectural claim that the same Cedar policy produces semantically equivalent receipts regardless of the sandbox backend, with tamper-evidence and chain linkage guarantees. The implementation is well-documented and adheres to the project's conventions.
Below are detailed observations and actionable feedback:
🔴 CRITICAL: Security Issues
-
Tamper-evidence scope validation:
- The
sandbox_backendfield is claimed to be inside the signature scope, ensuring tamper-evidence. However, the implementation does not explicitly validate whether other critical fields (e.g.,ring,policy_digest) are also protected within the signature scope. If these fields are tampered with, it could lead to security bypasses. - Action: Add explicit tests to verify that all critical fields (
ring,policy_digest,previousReceiptHash) are covered by the signature scope. This ensures that tampering with any field invalidates the receipt.
- The
-
Receipt chain linkage integrity:
- The
previousReceiptHashfield is used for chain linkage, but there is no explicit validation in the code to ensure that the hash matches the previous receipt's canonicalized payload. This could allow an attacker to inject a fake receipt into the chain. - Action: Add a validation step in
verify_receiptto ensurepreviousReceiptHashmatches the hash of the prior receipt's canonicalized payload.
- The
🟡 WARNING: Potential Breaking Changes
-
Dependency on
sb_runtime_agentmeshskill:- The example assumes the
sb_runtime_agentmeshskill is installed and available. While this is acceptable for the example, it introduces a tight coupling that could break if the skill's API changes in the future. - Action: Document the exact version of
sb_runtime_agentmeshrequired for compatibility and consider pinning the dependency in the example's README.
- The example assumes the
-
Policy backward compatibility:
- The example uses a specific Cedar policy format (
sandbox-policy.yaml). If the policy schema evolves, this example may break. - Action: Add a compatibility note in the README specifying the Cedar policy schema version used.
- The example uses a specific Cedar policy format (
💡 Suggestions for Improvement
-
Thread safety in concurrent execution:
- The
GovernanceSkillclass is instantiated separately for each scenario, which avoids shared state issues. However, if the skill is reused across threads in other contexts, thread safety could become a concern. - Action: Add a note in the
GovernanceSkilldocumentation clarifying its thread-safety guarantees (e.g., whether it is safe to use across threads).
- The
-
Enhanced tamper-evidence demonstration:
- The tamper-evidence test flips the
sandbox_backendfield but does not demonstrate tampering with other fields likeringorpolicy_digest. - Action: Extend the tamper-evidence test to modify additional fields and confirm verification fails.
- The tamper-evidence test flips the
-
Policy engine correctness:
- The policy rules in
sandbox-policy.yamlrely on regex-based matching (matches,contains). Regex-based policies can be error-prone and may lead to false negatives or positives. - Action: Add unit tests for the policy engine to ensure correct behavior for edge cases (e.g., partial matches, malformed actions).
- The policy rules in
-
Documentation clarity:
- The README is comprehensive but could benefit from a visual diagram illustrating the receipt generation and verification process across sandbox backends.
- Action: Add a simple flowchart or diagram to the README to improve clarity for new users.
-
External verifier integration:
- The example mentions
@veritasacta/verifyfor offline verification but does not include automated tests to confirm compatibility with this tool. - Action: Add a CI step to run
@veritasacta/verifyagainst the generated receipts to ensure compatibility.
- The example mentions
Code Quality Observations
-
Hardcoded agent DID:
- The agent DID (
did:mesh:sb-runtime-demo-agent) is hardcoded in the example. While acceptable for a demo, this could lead to confusion if reused in production. - Action: Parameterize the agent DID in
getting_started.pyto allow customization.
- The agent DID (
-
Receipt writing logic:
- The receipt writing logic in
write_receipts_to_diskusesjson.dumpswithindent=2andsort_keys=True. While this ensures readability, it may not match the canonicalization requirements for verification. - Action: Confirm that the written receipts match the canonicalization requirements of
@veritasacta/verify.
- The receipt writing logic in
-
Error handling:
- The
ImportErrorhandling forsb_runtime_agentmesh.skillis clear but could benefit from a more specific error message (e.g., checking if the skill directory exists). - Action: Enhance the error message to include troubleshooting steps for missing dependencies.
- The
Conclusion
This PR is well-structured and demonstrates the architectural claims effectively. However, critical security validations (tamper-evidence scope, chain linkage integrity) need to be strengthened to ensure robustness. Addressing these issues will enhance the security and reliability of the example. Additionally, minor improvements to documentation, testing, and error handling will improve usability and maintainability.
Recommended Actions:
- Address 🔴 CRITICAL issues immediately.
- Consider 🟡 WARNING items for long-term compatibility.
- Implement 💡 SUGGESTIONS to improve usability and robustness.
Let me know if you need further clarification or assistance!
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Code Review for examples: sb-runtime-governed — multi-backend receipt portability
This PR introduces a worked example demonstrating the portability of signed receipts across different sandbox backends (sb_runtime_builtin, nono, and openshell). The example validates the architectural claim that the same Cedar policy produces semantically equivalent receipts regardless of the sandbox backend, with the sandbox_backend field included in the signature scope for tamper-evidence.
🔴 CRITICAL Issues
-
Insufficient Validation of
sandbox_backendField:- The
sandbox_backendfield is critical for ensuring the integrity of the receipt. While the tamper-evidence test demonstrates that modifying this field invalidates the signature, the code does not explicitly validate that thesandbox_backendvalue is one of the expected values (sb_runtime_builtin,nono,openshell). This could allow an attacker to inject unexpected values into the field, potentially bypassing downstream logic that relies on this field. - Recommendation: Add explicit validation for the
sandbox_backendfield in theGovernanceSkillclass to ensure it matches one of the expected values.
- The
-
Potential Replay Attack on Receipts:
- The
previousReceiptHashfield is used for chain linkage, but there is no mechanism to ensure that the chain is unique or that the same receipt cannot be replayed in a different context. This could allow an attacker to replay a valid receipt in a different scenario. - Recommendation: Introduce a nonce or timestamp in the receipt payload to ensure uniqueness and prevent replay attacks. This should also be included in the signature scope.
- The
-
Lack of Cryptographic Key Rotation:
- The example uses a single operator key (
Signer.generate()) for signing receipts, but there is no demonstration or mention of how key rotation would be handled. This is a critical consideration for long-term security. - Recommendation: Add documentation or an example demonstrating how to handle key rotation and how to verify receipts signed with both old and new keys.
- The example uses a single operator key (
🟡 WARNING Issues
-
Backward Compatibility:
- While this PR does not introduce changes outside the
examples/sb-runtime-governed/directory, it relies on thesb-runtime-skillpackage introduced in #1203. If any changes are made to thesb-runtime-skillAPI in the future, this example may break. - Recommendation: Add a compatibility test to ensure that future changes to
sb-runtime-skilldo not break this example.
- While this PR does not introduce changes outside the
-
Policy Changes:
- The
sandbox-policy.yamlfile is shared across all three scenarios. If this policy is updated in the future, it may affect the behavior of this example. - Recommendation: Consider versioning the policy file or documenting its expected behavior to ensure future changes do not unintentionally break the example.
- The
💡 Suggestions for Improvement
-
Thread Safety:
- The
GovernanceSkillclass is instantiated separately for each scenario, which avoids thread-safety issues in this example. However, if this class is used in a multi-threaded context in the future, ensure that theSignerandGovernanceSkillclasses are thread-safe. - Recommendation: Add a note in the
GovernanceSkillandSignerclass documentation about their thread-safety guarantees.
- The
-
Type Safety:
- The
ScenarioResultdataclass could benefit from type annotations for thereceiptsfield to specify the expected structure of the receipt dictionaries. - Recommendation: Define a Pydantic model for the receipt structure and use it in the
ScenarioResultdataclass to enforce type safety.
- The
-
Error Handling:
- The
verify_receiptfunction is used to validate receipts, but there is no detailed error handling for cases where verification fails. This could make debugging more difficult. - Recommendation: Enhance the error handling in
verify_receiptto provide more detailed error messages, such as whether the failure was due to an invalid signature, a missing field, or a mismatch in thesandbox_backend.
- The
-
Documentation:
- The README is comprehensive, but it could benefit from a section on potential security considerations, such as the importance of key rotation and the risks of replay attacks.
- Recommendation: Add a "Security Considerations" section to the README to discuss these issues and provide guidance on mitigating them.
-
Test Coverage:
- The example includes a
# pragma: no covercomment in several places, which could lead to gaps in test coverage. - Recommendation: Write additional tests to cover these cases, or remove the
# pragma: no covercomments if they are not necessary.
- The example includes a
-
Policy Engine Correctness:
- The
sandbox-policy.yamlfile uses regex-based conditions, which can be error-prone and may lead to false negatives or positives if the regex patterns are not carefully crafted. - Recommendation: Add unit tests for the policy engine to ensure that the regex patterns match the intended actions and do not introduce false negatives or positives.
- The
-
External Dependencies:
- The example relies on the
@veritasacta/verifyCLI tool for external verification. While this is a useful demonstration, it introduces an external dependency that may not always be available. - Recommendation: Provide an alternative Python-based verification script using the
cryptographylibrary to make the example fully self-contained.
- The example relies on the
-
Code Readability:
- The
print_verify_instructionsfunction could be enhanced to include a brief explanation of the verification process for users who may not be familiar with the@veritasacta/verifytool. - Recommendation: Add comments or inline explanations in the function to make it more beginner-friendly.
- The
Summary
This PR is a well-structured and comprehensive example that effectively demonstrates the architectural claims of the sb-runtime integration. However, there are critical security issues related to the validation of the sandbox_backend field, replay attack prevention, and key rotation that must be addressed. Additionally, there are some potential backward compatibility concerns and opportunities for improving type safety, error handling, and documentation.
Action Items:
- 🔴 Add validation for the
sandbox_backendfield in theGovernanceSkillclass. - 🔴 Introduce a mechanism to prevent replay attacks (e.g., nonce or timestamp in the receipt payload).
- 🔴 Document or demonstrate key rotation for the operator key.
- 🟡 Add compatibility tests for the
sb-runtime-skillpackage. - 🟡 Consider versioning the
sandbox-policy.yamlfile or documenting its expected behavior. - 💡 Add notes about thread safety in the
GovernanceSkillandSignerclasses. - 💡 Use Pydantic models for receipt structure validation.
- 💡 Enhance error handling in the
verify_receiptfunction. - 💡 Add a "Security Considerations" section to the README.
- 💡 Write unit tests for the policy engine's regex patterns.
- 💡 Provide a Python-based alternative to the
@veritasacta/verifytool for receipt verification. - 💡 Improve the readability of the
print_verify_instructionsfunction.
Once the critical issues are addressed, this PR will be ready for merging.
imran-siddique
left a comment
There was a problem hiding this comment.
Completing the 3-PR sequence from #748. sb-runtime governed example under examples/ — extension path, good tests.
… 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 3 (final) in the three-PR sequence proposed on #748. Adds a runnable worked example at
examples/sb-runtime-governed/that demonstrates the architectural claim of the sb-runtime integration:Completes the sequence proposed on #748:
docs/integrations/sb-runtime.mdpackages/agentmesh-integrations/sb-runtime-skill/What the demo does
Runs the same six actions (three allowed, three denied) across three sandbox-backend configurations using the same Cedar policy and the same operator Ed25519 key:
sandbox_backendstandalonesb_runtime_builtinnonononoopenshellopenshellThen:
sb_runtime_agentmeshat verify time).sandbox_backendon a receipt and confirming verification fails (the field is inside the signature scope, not sidecar metadata).receipt[1].previousReceiptHash == sha256(canonical(receipt[0])).examples/sb-runtime-governed/receipts/(gitignored) so the output is inspectable and re-verifiable with external tooling (npx @veritasacta/verify).Files
No changes outside
examples/sb-runtime-governed/.Test plan
python examples/sb-runtime-governed/getting_started.pyexits 0sandbox_backendfails verificationpreviousReceiptHashmatchessha256(canonical(prior envelope))receipts/subdirectory (gitignored), re-verifiable withnpx @veritasacta/verifyDependencies
pyyaml>=6,<7(same asopenshell-skill)cryptography>=41(for Ed25519 + JCS canonicalization)Both are declared in the
sb-runtime-skillpyproject.toml shipped in #1203. No new dependencies introduced at the AGT level.Notes
examples/openshell-governed/(same action set, same three-allow-three-deny structure) so cross-example comparison is straightforward. Whereopenshell-governeddemonstrates the policy contract alone, this example extends it with the signed-receipt layer (distinctive value-add) and the multi-backend portability claim.sandbox_backend="nono"as declared configuration; a future revision (coordinated with the nono Python library upstream) will wire in actual runtime enforcement. The current example demonstrates the receipt-layer portability claim, which is independent of whether a real nono runtime is doing the sandboxing.Cc @imran-siddique (closing the three-PR sequence as committed on #748), @lukehinds (the nono scenario follows the composition pattern documented in #1202; happy to match nono's native CLI flag conventions or capability-file layout when the Python library is wired for actual runtime enforcement).