Microsoft Agent Governance Toolkit (AGT) policy enforcement for Strands Agents.
Provides a deterministic, YAML-based InterventionHandler that gates tool calls before execution — no model judgment involved.
pip install strands-agtfrom strands import Agent
from strands_agt import AGTGovernance
governance = AGTGovernance(policies="policies.yaml")
agent = Agent(tools=[...], interventions=[governance])
result = agent("search for documents")Policies are defined in YAML:
policies:
- name: allow-search
effect: allow
actions: ["search"]
principals: ["User::*"]
- name: deny-delete
effect: deny
actions: ["delete_file"]
reason: "File deletion is not permitted"| Effect | Strands Action | Behavior |
|---|---|---|
allow |
Proceed() |
Tool executes normally |
deny |
Deny(reason=...) |
Tool is blocked, reason shown to model |
steer |
Guide(feedback=...) |
Tool is blocked with corrective guidance |
- Deny policies are checked first — first match short-circuits
- Steer policies are checked next
- Allow policies are checked last — first match permits
- No match = deny (fail-closed)
governance = AGTGovernance(
policies="role_policies.yaml",
principal_resolver=lambda state: {
"type": state.get("user_role", "User"),
"id": state.get("user_id", "anonymous"),
},
)
agent = Agent(tools=[...], interventions=[governance])
agent("Delete backups", invocation_state={"user_role": "Admin", "user_id": "alice"})policies:
- name: rate-limited-email
effect: allow
actions: ["send_email"]
conditions:
session.call_count:
lt: 5governance = AGTGovernance(
policies="env_policies.yaml",
context_enricher=lambda ctx: {
"environment": os.environ.get("DEPLOY_ENV", "development"),
"tenant_id": ctx["invocation_state"].get("tenant_id"),
},
)Conditions support: lt, lte, gt, gte, eq, neq, in.
conditions:
session.call_count:
lt: 10
input.database:
in: ["analytics", "staging"]| Parameter | Type | Default | Description |
|---|---|---|---|
policies |
str | list[str] |
required | YAML policy file path(s) or inline YAML |
principal |
dict[str, str] | None |
{"type": "User", "id": "anonymous"} |
Static principal identity |
principal_resolver |
Callable | None |
None |
Dynamic resolver from invocation_state |
context_enricher |
Callable | None |
None |
Injects extra fields into policy context |
on_error |
str |
"throw" |
Error mode: "throw", "proceed", or "deny" |
pip install -e ".[dev]"
pytest
ruff check src tests
mypy src