Repository navigation
feat(agent-mesh): wire GovernedCallable into hypervisor ring enforcement - #2731
Darshan Poudel (rsd-darshan) wants to merge 1 commit into
Conversation
Closes microsoft#2667. - Add `ring` and `session_id` fields to `GovernanceConfig`; default `ring=None` leaves existing behaviour completely unchanged. - `GovernedCallable.__init__` lazily instantiates `RingEnforcer` and `RingBreachDetector` when a ring is configured. - New `_check_ring()` runs before `PolicyEngine.evaluate()`: infers the resource type from the action string, calls `check_resource()`, trips the circuit breaker on repeated violations, and injects `ring.*` constraint fields into the evaluation context so policy rules can reference them. - Re-export `ExecutionRing`, `ResourceType`, `ResourceConstraints`, `RING_CONSTRAINTS`, and `RingCheckResult` from `agentmesh.governance`. - Add `agent_hypervisor>=4.0.0,<5.0` to package dependencies. - New `TestRingEnforcement` test class covering ring-level allow/deny, context injection, on_deny callback, and circuit-breaker behaviour.
|
Welcome to the Agent Governance Toolkit! Thanks for your first pull request. |
|
🟡 Contributor Check: MEDIUM
Automated check by AGT Contributor Check. |
🤖 AI Agent: contributor-guide — View details
Welcome, and thank you for your contribution to the project! 🎉 Great job on providing detailed documentation and comprehensive test cases for the new Before merging, please address the following:
For more details on contributing, please review our CONTRIBUTING.md. Let us know if you have any questions! |
…#2731 + hardening) (#2761) * fix(audit): remove duplicate AuditEntry fields, align on compute_driver per spec (#2527) AuditEntry declared sandbox_id, environment, and container_runtime twice. Pydantic v2 keeps the last declaration, which used compute_driver (matching AUDIT-COMPLIANCE-1.0 spec). Remove duplicates and align all references. - Remove duplicate field declarations in AuditEntry - Rename _EnvContext.container_runtime to compute_driver - Read OPENSHELL_COMPUTE_DRIVER env var (not CONTAINER_RUNTIME) - Update SignedAuditEntry field and from_entry() mapping - Update test assertions Closes #2474 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Imran Siddique <imran.siddique@microsoft.com> * feat(rust): add feature-gated agt operator CLI (policy/audit/trust) (#2513) * fix(rust): migrate cedar Request::new to cedar-policy 4.x API The cedar-policy 2.4.2 -> 4.11.0 bump (#2418) updated Cargo.toml but not the code, so cargo build -p agentmesh fails: cedar 4.x's Request::new takes concrete EntityUids (not Option), an extra Option<&Schema>, and returns a Result. Absent principal/action/resource now map to a reserved <Type>::"__unspecified__" placeholder, preserving the prior behavior where an unspecified entity satisfied an unconstrained scope but no equality constraint. All existing tests pass unchanged. * feat(rust): add feature-gated agt operator CLI Add an operator-facing 'agt' binary to the agentmesh crate behind an opt-in 'cli' feature; the default library build pulls no argument parser and produces no binary. The CLI is a thin consumer of existing crate APIs and adds no new library surface. Commands: - agt check --policy <file> --input <json> -- evaluate a request against a policy; one-line JSON to stdout, exit 0 allow / 1 not-allowed / 2 input error. - agt policy validate|explain -- validate a policy file; explain a decision. - agt audit tail|export -- read/re-emit a serialized audit log (json|ndjson). - agt trust show|set -- read/update a file-backed trust store, fail-closed. Fail-closed throughout: invalid input exits non-zero with a structured 'error:'. Integration tests (assert_cmd) cover the happy path and each fail-closed path, gated behind the 'cli' feature so the default test run is unaffected. Also adds a .gitignore negation so the Rust src/bin/ source is tracked (the build-output **/[Bb]in/* rule was matching it). Implements the proposal in #2445. * docs: add CHANGELOG entries for the agt CLI and cedar 4.x build fix Addresses the Docs Sync check on #2513: documents the new feature-gated agt operator CLI under [Unreleased] Added, and the cedar-policy 4.x Request::new migration under [Unreleased] Fixed. * chore: restore upstream rust metadata Signed-off-by: Imran Siddique <imran.siddique@microsoft.com> * fix(governance): export FacetRegistry and extract_protocol_facets from agentmesh.governance (#2598) FacetRegistry, extract_protocol_facets and default_registry were added in the wire protocol facets PR but never added to the governance __init__.py. Users trying to register custom protocol extractors had to import directly from the internal module path instead of the public package surface. Signed-off-by: Imran Siddique <imran.siddique@microsoft.com> * fix: register consolidated packages in CI checks and pre-install for tests (#2685) - Add agent-governance-toolkit-{core,integrations,cli,protocols} to REGISTERED_PACKAGES in check_dependency_confusion.py - Add same to notebook-pip-audit REGISTERED set in ci.yml - Pre-install consolidated packages from local source (--no-deps -e) before test jobs, since they are not yet on PyPI Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Imran Siddique <imran.siddique@microsoft.com> * chore(deps): bump ai and @mastra/core (#2700) Removes [ai](https://github.com/vercel/ai/tree/HEAD/packages/ai). It's no longer used after updating ancestor dependency [@mastra/core](https://github.com/mastra-ai/mastra/tree/HEAD/packages/core). These dependencies need to be updated together. Removes `ai` Updates `@mastra/core` from 0.10.0 to 1.37.1 - [Release notes](https://github.com/mastra-ai/mastra/releases) - [Changelog](https://github.com/mastra-ai/mastra/blob/main/docs/CHANGELOG.md) - [Commits](https://github.com/mastra-ai/mastra/commits/@mastra/core@1.37.1/packages/core) --- updated-dependencies: - dependency-name: ai dependency-version: dependency-type: indirect - dependency-name: "@mastra/core" dependency-version: 1.37.1 dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Imran Siddique <imran.siddique@microsoft.com> * feat(agent-mesh): wire GovernedCallable into hypervisor ring enforcement Closes #2667. - Add `ring` and `session_id` fields to `GovernanceConfig`; default `ring=None` leaves existing behaviour completely unchanged. - `GovernedCallable.__init__` lazily instantiates `RingEnforcer` and `RingBreachDetector` when a ring is configured. - New `_check_ring()` runs before `PolicyEngine.evaluate()`: infers the resource type from the action string, calls `check_resource()`, trips the circuit breaker on repeated violations, and injects `ring.*` constraint fields into the evaluation context so policy rules can reference them. - Re-export `ExecutionRing`, `ResourceType`, `ResourceConstraints`, `RING_CONSTRAINTS`, and `RingCheckResult` from `agentmesh.governance`. - Add `agent_hypervisor>=4.0.0,<5.0` to package dependencies. - New `TestRingEnforcement` test class covering ring-level allow/deny, context injection, on_deny callback, and circuit-breaker behaviour. Signed-off-by: Imran Siddique <imran.siddique@microsoft.com> * fix(agent-mesh): shared breach detector + exact-token resource inference Two security hardenings on top of the ring enforcement wiring from #2731: 1. RingBreachDetector is now shared per (agent_id, session_id) via a module-level registry. Previously each GovernedCallable held its own detector, so an agent with N tools could spend the full violation budget N times before the circuit breaker tripped. 2. Resource-type inference uses exact-token match (split on non-alphanumerics) instead of substring containment. Substring matching produced false positives like 'set_httponly_flag' inferring NETWORK and 'overwrite_protection_check' inferring FILESYSTEM. Adds 6 new tests covering both fixes. Co-authored-by: rsd-darshan <poudeldarshan44@gmail.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Imran Siddique <imran.siddique@microsoft.com> * fix(agent-mesh): make agent_hypervisor an optional extra The hypervisor package is not yet published at v4 on PyPI. Moving it to a [hypervisor] extra keeps the core install resolvable. Ring enforcement imports remain lazy, so this is a no-op for users who never set config.ring. The dev extra still pulls it in so tests exercise the real RingEnforcer/RingBreachDetector. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Imran Siddique <imran.siddique@microsoft.com> * chore(cspell): add httponly and execve to repo dictionary Signed-off-by: Imran Siddique <imran.siddique@microsoft.com> * ci: trigger pull_request workflows Signed-off-by: Imran Siddique <imran.siddique@microsoft.com> * test(agent-mesh): autouse reset of shared breach detector Add an autouse fixture in TestRingEnforcement that calls _reset_shared_breach_detectors before and after each test. The shared detector now persists across tests by design (singleton per agent/session), which would otherwise let an earlier test's circuit breaker bleed into a later one's assertions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Imran Siddique <imran.siddique@microsoft.com> --------- Signed-off-by: Imran Siddique <imran.siddique@microsoft.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Kerberosmansour <13433538+kerberosmansour@users.noreply.github.com> Co-authored-by: Dipika Ranabhat <59753519+qubeena07@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: rsd-darshan <poudeldarshan44@gmail.com> Co-authored-by: Imran Siddique <mosiddi@microsoft.com>
|
Superseded by #2761 which was merged. Thanks Darshan Poudel (@rsd-darshan) — credit preserved as co-author. Hardened with shared breach-detector and exact-token resource inference; tests added. |
Summary
Closes #2667. Paired with #2666 — ships atomically per maintainer note.
ringandsession_idfields toGovernanceConfig;ring=None(default) leaves all existing behaviour unchangedGovernedCallable.__init__()lazily instantiatesRingEnforcerandRingBreachDetectoronly when a ring is configured_check_ring()runs beforePolicyEngine.evaluate(): infers the resource type from the action string, callscheck_resource(), records violations withRingBreachDetector, trips the circuit breaker on repeated attempts, and injectsring.*constraint fields into the evaluation context so policy rules can reference them (e.g.ring.subprocess_allowed == false)ExecutionRing,ResourceType,ResourceConstraints,RING_CONSTRAINTS,RingCheckResultfromagentmesh.governanceagent_hypervisor>=4.0.0,<5.0to package dependenciesTest plan
TestRingEnforcement— 9 new tests inagent-mesh/tests/test_govern.pyring=Nonering.*context fields injected for policy ruleson_denycallback receives ring denial decisionTestGovernsuite passes unchanged (no existing behaviour altered)