Repository navigation
[Bug]: agent-mesh PolicyRule splits and/or inside quoted literals, so deny rules match every request and allow rules never match #4291
Description
Package
agent-mesh
Description
PolicyRule._eval_expression in agentmesh/governance/policy.py (lines 215-223 on main) splits a condition with expr.split(" or ") and then expr.split(" and "), without checking for quotes. A condition such as tool.name == 'search and replace' is split into tool.name == 'search and replace'. Neither half is valid syntax, so each goes to the unrecognized-syntax fallback:
- For a
denyrule, the fallback fails closed and returns MATCH, so the rule matches every request, includingread_file. - For an
allowrule, the fallback returns NO-MATCH, so the rule never matches, not even for the exact value'read or list'.
The standalone _eval_expression in agentmesh/governance/federation.py (lines 1063-1071), which OrgPolicyRule uses, has the same split.
The atomic regexes accept spaces inside literals ([^'"]+), so 'search and replace' is valid input. The other SDKs already handle this case. The .NET PolicyRule.SplitCompound tracks quote state (#146), and the TypeScript evaluateExpression uses splitOutsideQuotes (#2107). Only the Python evaluators still split inside quotes.
This is a correctness bug rather than a bypass: for deny rules it over-denies, and for allow rules it under-allows.
How does this impact your work?
Any agent-mesh or federation policy with a deny rule whose literal contains and or or blocks every tool call, and an allow rule with such a literal never grants access. Nothing in the policy file shows why; the only sign is a warning in the log.
Timeline
No hard deadline
Steps to Reproduce
On main at ae8c1ae, from agent-governance-python/agent-mesh:
from agentmesh.governance.federation import OrgPolicyRule
from agentmesh.governance.policy import PolicyRule
deny = PolicyRule(name="d", condition="tool.name == 'search and replace'", action="deny")
allow = PolicyRule(name="a", condition="tool.name == 'read or list'", action="allow")
org = OrgPolicyRule(name="o", condition="tool.name == 'search and replace'", action="deny")
print(deny.evaluate({"tool": {"name": "read_file"}})) # True, expected False
print(allow.evaluate({"tool": {"name": "read or list"}})) # False, expected True
print(org.evaluate({"tool": {"name": "read_file"}})) # True, expected FalseExpected: a quoted literal is opaque, so the deny rules match only search and replace, and the allow rule matches read or list. This is how the .NET and TypeScript evaluators behave.
Actual: both deny rules match read_file, and the allow rule does not match its own value.
Environment
macOS 26 (arm64), Python 3.12.13, agent-mesh 5.0.0 from source at main ae8c1ae.
Logs / Error Output
Policy rule 'd': unrecognized condition syntax "tool.name == 'search" — treating as MATCH
Policy rule 'd': unrecognized condition syntax "replace'" — treating as MATCH
Policy rule 'a': unrecognized condition syntax "tool.name == 'read" — treating as NO-MATCH
Policy rule 'a': unrecognized condition syntax "list'" — treating as NO-MATCH
OrgPolicyRule: unrecognized condition syntax "tool.name == 'search" — treating as MATCH
OrgPolicyRule: unrecognized condition syntax "replace'" — treating as MATCH
Suggested fix
Add a small _split_outside_quotes(expr, sep) helper to policy.py that tracks single- and double-quote state, the way the TypeScript splitOutsideQuotes does. Use it for the OR split and then the AND split in both PolicyRule._eval_expression and the federation.py _eval_expression, and fall through to the atomic checks when no separator appears outside quotes. I have a fix with regression tests ready and will open the PR for this issue myself.
Code of Conduct
- I agree to follow the Microsoft Open Source Code of Conduct
Activity
Zhuoxi2000 commentedon Oct 12, 2026
I'd like to take this one myself. The fix and regression tests are ready, and I'll open the PR linked to this issue.
github-actions commentedon Oct 12, 2026
Welcome to the Agent Governance Toolkit! Thanks for opening your first issue.
A maintainer will review this shortly. Check our Contributing Guide.
For security issues, use private vulnerability reporting.
github-actions commentedon Oct 12, 2026
🔴 Contributor Check: HIGH
Automated check by AGT Contributor Check.