Metadata-Version: 2.4
Name: strands-agt
Version: 0.1.0
Summary: Microsoft Agent Governance Toolkit (AGT) policy enforcement for Strands Agents
Project-URL: Homepage, https://github.com/lizradway/strands-agt
Project-URL: Documentation, https://github.com/lizradway/strands-agt#readme
Project-URL: Repository, https://github.com/lizradway/strands-agt
Project-URL: Issues, https://github.com/lizradway/strands-agt/issues
Author: Liz Radway
License: Apache-2.0
License-File: LICENSE
Keywords: agents,agt,ai,governance,policy,strands
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Requires-Dist: pyyaml>=6.0.0
Requires-Dist: strands-agents>=1.29.0
Provides-Extra: dev
Requires-Dist: hatch; extra == 'dev'
Requires-Dist: mypy<2.0.0,>=1.15.0; extra == 'dev'
Requires-Dist: pytest-asyncio<1.0.0,>=0.25.0; extra == 'dev'
Requires-Dist: pytest<9.0.0,>=8.0.0; extra == 'dev'
Requires-Dist: ruff<1.0.0,>=0.11.0; extra == 'dev'
Requires-Dist: types-pyyaml>=6.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# strands-agt

Microsoft [Agent Governance Toolkit (AGT)](https://github.com/microsoft/agent-governance-toolkit) policy enforcement for [Strands Agents](https://github.com/strands-agents/harness-sdk).

Provides a deterministic, YAML-based `InterventionHandler` that gates tool calls before execution — no model judgment involved.

## Installation

```bash
pip install strands-agt
```

## Quick Start

```python
from strands import Agent
from strands_agt import AGTGovernance

governance = AGTGovernance(policies="policies.yaml")
agent = Agent(tools=[...], interventions=[governance])
result = agent("search for documents")
```

## Policy Format

Policies are defined in YAML:

```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"
```

### Effects

| 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 |

### Evaluation Order

1. Deny policies are checked first — first match short-circuits
2. Steer policies are checked next
3. Allow policies are checked last — first match permits
4. No match = **deny** (fail-closed)

## Features

### Role-Based Access

```python
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"})
```

### Rate Limiting

```yaml
policies:
  - name: rate-limited-email
    effect: allow
    actions: ["send_email"]
    conditions:
      session.call_count:
        lt: 5
```

### Context Enrichment

```python
governance = AGTGovernance(
    policies="env_policies.yaml",
    context_enricher=lambda ctx: {
        "environment": os.environ.get("DEPLOY_ENV", "development"),
        "tenant_id": ctx["invocation_state"].get("tenant_id"),
    },
)
```

### Condition Operators

Conditions support: `lt`, `lte`, `gt`, `gte`, `eq`, `neq`, `in`.

```yaml
conditions:
  session.call_count:
    lt: 10
  input.database:
    in: ["analytics", "staging"]
```

## Configuration

| 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"` |

## Development

```bash
pip install -e ".[dev]"
pytest
ruff check src tests
mypy src
```

## References

- [Microsoft AGT](https://github.com/microsoft/agent-governance-toolkit)
- [Strands Agents](https://github.com/strands-agents/harness-sdk)
- [Strands Interventions docs](https://strandsagents.com/latest/user-guide/concepts/agents/interventions/)
