Skip to content

feat(agent-mesh): wire GovernedCallable into hypervisor ring enforcement - #2731

Closed
Darshan Poudel (rsd-darshan) wants to merge 1 commit into
microsoft:mainfrom
rsd-darshan:feat/governed-callable-ring-enforcement
Closed

Darshan Poudel (rsd-darshan) wants to merge 1 commit into
microsoft:mainfrom
rsd-darshan:feat/governed-callable-ring-enforcement

Conversation

@rsd-darshan

Copy link
Copy Markdown
Contributor

Summary

Closes #2667. Paired with #2666 — ships atomically per maintainer note.

  • Add ring and session_id fields to GovernanceConfig; ring=None (default) leaves all existing behaviour unchanged
  • GovernedCallable.__init__() lazily instantiates RingEnforcer and RingBreachDetector only when a ring is configured
  • New _check_ring() runs before PolicyEngine.evaluate(): infers the resource type from the action string, calls check_resource(), records violations with RingBreachDetector, trips the circuit breaker on repeated attempts, and injects ring.* constraint fields into the evaluation context so policy rules can reference them (e.g. ring.subprocess_allowed == false)
  • Re-export ExecutionRing, ResourceType, ResourceConstraints, RING_CONSTRAINTS, RingCheckResult from agentmesh.governance
  • Add agent_hypervisor>=4.0.0,<5.0 to package dependencies

Test plan

  • TestRingEnforcement — 9 new tests in agent-mesh/tests/test_govern.py
    • Ring 3 denies subprocess-type action
    • Ring 3 denies network-type action
    • Ring 3 allows generic tool-execution action
    • Ring 2 allows subprocess and network actions
    • No enforcement when ring=None
    • ring.* context fields injected for policy rules
    • on_deny callback receives ring denial decision
    • Ring denial never reaches policy engine
    • Circuit breaker trips after repeated violations
  • Existing TestGovern suite passes unchanged (no existing behaviour altered)

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.
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown

Welcome to the Agent Governance Toolkit! Thanks for your first pull request.
Please ensure tests pass, code follows style (ruff check), and you have signed the CLA.
See our Contributing Guide.

@github-actions github-actions Bot added dependencies Pull requests that update a dependency file tests agent-mesh agent-mesh package size/L Large PR (< 500 lines) labels Jun 1, 2026
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown

🟡 Contributor Check: MEDIUM

Check Result
Profile MEDIUM
Credential NONE
Overall MEDIUM

Automated check by AGT Contributor Check.

@github-actions github-actions Bot added the needs-review:MEDIUM Contributor check flagged MEDIUM risk label Jun 1, 2026
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
🤖 AI Agent: contributor-guide — View details

AI-generated review output. Treat it as untrusted analysis and verify before acting.

Welcome, and thank you for your contribution to the project! 🎉

Great job on providing detailed documentation and comprehensive test cases for the new RingEnforcement feature.

Before merging, please address the following:

  1. Ensure that all new dependencies (e.g., agent_hypervisor) are documented in the relevant sections of the repository, such as the README or installation guides.
  2. Verify that the TestRingEnforcement suite passes successfully in the CI pipeline.

For more details on contributing, please review our CONTRIBUTING.md. Let us know if you have any questions!

Imran Siddique (imran-siddique) added a commit that referenced this pull request Jun 2, 2026
…#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>
@imran-siddique

Copy link
Copy Markdown
Collaborator

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-mesh agent-mesh package dependencies Pull requests that update a dependency file needs-review:MEDIUM Contributor check flagged MEDIUM risk size/L Large PR (< 500 lines) tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: wire GovernedCallable into hypervisor ring enforcement

2 participants