The policy engine is the single enforcement point through which every governed agent action flows. Before any tool is called, any response is returned, or any resource is accessed, the engine evaluates declarative rules against the agent’s runtime context and returns a structured decision — typically in sub-millisecond time. It operates at two layers: a declarative layer of YAML/JSONDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/microsoft/agent-governance-toolkit/llms.txt
Use this file to discover all available pages before exploring further.
PolicyDocument files evaluated by the PolicyEvaluator, and an integration layer of GovernancePolicy objects applied by framework adapters to intercept tool calls, enforce token limits, and check blocked patterns at runtime.
Policy YAML Syntax
Every policy file follows the same schema. Theversion, name, and description fields provide metadata; rules lists the enforcement logic; and defaults defines the fallback when no rule matches.
The
defaults.action field defaults to deny in the Python SDK so that a policy file with no matching rules does not silently permit actions. Set it to allow explicitly if your intent is a permissive baseline.PolicyDocument fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
version | string | No | "1.0" | Schema version identifier |
name | string | No | "unnamed" | Human-readable name for audit logs |
description | string | No | "" | Free-form description |
rules | array | No | [] | Ordered list of PolicyRule objects |
defaults | object | No | see below | Fallback settings when no rule matches |
inherit | boolean | No | true | Whether parent policies are loaded during folder-level discovery |
scope | string or null | No | null | Glob pattern restricting which action paths this policy applies to |
PolicyRule fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | Yes | — | Unique rule identifier within the document |
condition | PolicyCondition | Yes | — | The matching condition (field/operator/value triple) |
action | PolicyAction | Yes | — | Action to take when the condition matches |
priority | integer | No | 0 | Higher values are evaluated first |
message | string | No | "" | Explanation included in decisions and audit entries |
override | boolean | No | false | If true, replaces a parent rule with the same name during folder-level merge |
PolicyDefaults fields
| Field | Type | Default | Description |
|---|---|---|---|
action | PolicyAction | "deny" | Default action when no rule matches |
max_tokens | integer | 4096 | Maximum tokens per request |
max_tool_calls | integer | 10 | Maximum tool invocations per request |
confidence_threshold | float | 0.8 | Minimum confidence score (0.0–1.0) |
Condition Operators
APolicyCondition contains exactly three fields: field (a dot-path into the execution context), operator, and value.
| Operator | Semantics | Example |
|---|---|---|
eq | Context value equals target value | tool_name eq "execute_code" |
ne | Context value does not equal target value | agent_id ne "admin" |
gt | Context value is greater than target | token_count gt 4096 |
lt | Context value is less than target | confidence lt 0.8 |
gte | Context value is greater than or equal to target | confidence gte 0.8 |
lte | Context value is less than or equal to target | retries lte 3 |
in | Context value is a member of target collection | tool_name in ["read", "write"] |
not_in | Context value is NOT a member of target collection | tool_name not_in ["execute_code", "run_shell"] |
contains | Target value is contained within context value | arguments contains "password" |
matches | Context value matches target regex (search semantics) | tool_name matches "^exec_.*" |
Policy Actions
| Action | Allowed? | Semantics |
|---|---|---|
allow | Yes | The action is permitted. decision.allowed = True. |
deny | No | The action is blocked. The agent must not proceed. |
audit | Yes | The action is permitted but must be logged for review. decision.allowed = True, entry written to audit trail. |
block | No | Alias for deny. Hard block with the rule message surfaced to the caller. |
allow and audit are considered allowing. Actions deny and block are considered denying.
Conflict Resolution
When multiple policies produce competing decisions for the same agent action, thePolicyConflictResolver in agentmesh.governance.conflict_resolution applies one of four strategies.
deny_overrides
Any deny wins. Among multiple denies, highest priority wins. This is the safest strategy and aligns with XACML deny-overrides semantics. Use for enterprise deployments with hard deny guardrails.
allow_overrides
Any allow wins. Among multiple allows, highest priority wins. Use for zero-trust baseline with explicit grants — exception-based governance where allows should override default-deny policies.
priority_first_match
Candidates are sorted by priority descending; the highest-priority candidate wins regardless of action type. This is the default strategy and mirrors how
PolicyEvaluator resolves rules within a single policy.most_specific_wins
Candidates are ranked by scope specificity: Agent > Organization > Tenant > Global. Within the same scope, priority breaks ties. Use for multi-tenant setups with org → team → agent layering.
ResolutionResult fields:
| Field | Type | Description |
|---|---|---|
winning_decision | CandidateDecision | The decision that prevailed |
strategy_used | ConflictResolutionStrategy | Which strategy was applied |
candidates_evaluated | int | Number of candidates considered |
conflict_detected | bool | True if there was a mix of allow and deny candidates |
resolution_trace | list[str] | Step-by-step log of the resolution logic |
PolicyEvaluator API
PolicyEvaluator is the engine that evaluates PolicyDocument objects against execution contexts.
load_policies(directory)
Loads all .yaml and .yml files from a directory. Can be called multiple times; rules from all loaded documents are merged and sorted by priority.
evaluate(context, dynamic_context=None)
Evaluates all loaded policy rules against the given context dictionary. Returns a PolicyDecision.
- Rules are sorted by
prioritydescending and evaluated in order. - The first matching rule determines the decision.
- If no YAML rule matches, external backends are consulted in registration order.
- If no backend produces a result, the default action from the first loaded policy applies.
add_backend(backend)
Registers an external policy backend. Backends are consulted in registration order when no YAML rule matches.
Convenience backend loaders
PolicyDecision Fields
Every call toevaluator.evaluate() returns a PolicyDecision:
Whether the action is permitted.
True for allow and audit actions; False for deny and block.Name of the rule that fired.
None if defaults applied or a backend was used.The action taken:
"allow", "deny", "audit", or "block".Human-readable explanation — the rule’s
message field, or a default description.Structured audit metadata including policy name, rule name, action, context snapshot, and UTC timestamp.
Structured adaptation hints from dynamic-context rules (e.g.,
backoff_seconds, blocked_tools, retry_after).audit_entry structure for a matched rule:
audit_entry also includes policy_chain — the ordered list of policy names in the merge chain. For backend evaluations, it includes backend and evaluation_ms.
External Policy Backends
AGT ships withOPABackend (OPA/Rego) and CedarBackend. Both implement the ExternalPolicyBackend protocol: a name property and an evaluate(context) method returning a BackendDecision.
A BackendDecision carries: allowed (bool), action (str), reason (str), backend (str), evaluation_ms (float | None), and error (str | None).
Fail-Closed Semantics
The policy engine enforces fail-closed semantics on all evaluation errors:- If the engine encounters an unhandled exception during evaluation, it denies the action.
- If a registered backend returns
error != null, the engine immediately denies and does not fall through to the next backend or the default action. - If no policies are loaded at all, the default decision is deny (matching the TypeScript and .NET SDKs).
ERROR level with full exception context.
Code Examples
Folder-Level Policy Hierarchy
Whenroot_dir is configured on PolicyEvaluator, governance files are discovered by walking the directory tree from the action path up to the root. At each level, governance.yaml is loaded. The chain is assembled root-first and merged into a single flat rule list.
The deny immutability invariant ensures that a parent deny rule can never be overridden by a child rule — even when the child sets override: true and a higher priority. This prevents more specific policies from defeating security-critical denials set at higher levels, matching Azure Policy semantics.