Metadata-Version: 2.4
Name: authzen-policy-backend
Version: 0.1.0
Summary: OpenID AuthZEN policy backend for Microsoft Agent Governance Toolkit
Project-URL: Homepage, https://github.com/EmpowerID/authzen-policy-backend
Project-URL: Documentation, https://github.com/EmpowerID/authzen-policy-backend#readme
Project-URL: Repository, https://github.com/EmpowerID/authzen-policy-backend
Author-email: EmpowerID <engineering@empowerid.com>
License-Expression: MIT
License-File: LICENSE
Keywords: agent-governance,ai-agent,authorization,authzen,mcp,openid,policy
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT 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
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx<1,>=0.27
Requires-Dist: pydantic<3,>=2.4
Provides-Extra: dev
Requires-Dist: mypy>=1.13; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.8; extra == 'dev'
Description-Content-Type: text/markdown

# authzen-policy-backend

**OpenID AuthZEN policy backend for the Microsoft Agent Governance Toolkit**

Connect any [AuthZEN](https://openid.net/specs/openid-authzen-authorization-api-1_0.html)-compliant Policy Decision Point (PDP) to Microsoft's [Agent Governance Toolkit](https://github.com/microsoft/agent-governance-toolkit) as a pluggable `ExternalPolicyBackend`.

```
┌────────────────────────────────────────────────────────────────┐
│                    Your AI Agent                                │
│  (LangGraph, OpenAI Agents, AutoGen, custom, ...)              │
└──────────────────────┬─────────────────────────────────────────┘
                       │ evaluate(context)
┌──────────────────────▼─────────────────────────────────────────┐
│            MS Agent Governance Toolkit                          │
│  PolicyEvaluator  →  YAML rules (fast local)                   │
│                   →  AuthZENBackend (this package)              │
└──────────────────────┬─────────────────────────────────────────┘
                       │ POST /access/v1/evaluation
┌──────────────────────▼─────────────────────────────────────────┐
│              AuthZEN PDP                                        │
│  (EmpowerNow ARIA, Cerbos, Aserto, or any compliant PDP)      │
│  → Obligations, Constraints, Advice, Delegation, Budget        │
└────────────────────────────────────────────────────────────────┘
```

## Why

The Agent Governance Toolkit provides in-process YAML policy evaluation and optional OPA/Cedar backends. For enterprise deployments, you need:

- **Centralized policy management** — one PDP governs all agents, not scattered YAML files
- **Standards-based authorization** — OpenID AuthZEN, not proprietary policy formats
- **Rich decisions** — obligations, constraints, budget limits, and denial advice beyond binary allow/deny
- **Delegation-aware identity** — user-bound agents with scoped capabilities
- **Audit-grade decisions** — decision IDs that link to cryptographic receipts

This package bridges that gap with a single `add_backend()` call.

## Installation

```bash
pip install authzen-policy-backend
```

ARIA-enhanced features (obligations, constraints, denial advice extraction) are
included in the base package — no extras required.

## Quick Start

### Static Bearer Token (simplest)

```python
from agent_os.policies import PolicyEvaluator
from authzen_backend import AuthZENBackend

evaluator = PolicyEvaluator()
evaluator.add_backend(AuthZENBackend(
    pdp_url="https://pdp.example.com/access/v1/evaluation",
    pdp_application="my-agent-platform",
    token="my-bearer-token",
))

decision = evaluator.evaluate({
    "tool_name": "file_read",
    "agent_id": "travel-agent-1",
    "user_id": "alice",
})

print(decision.allowed)  # True/False
print(decision.reason)   # Human-readable reason from PDP
```

### Client Credentials (production)

```python
from authzen_backend import AuthZENBackend, ClientCredentialsAuth

backend = AuthZENBackend(
    pdp_url="https://pdp.example.com/access/v1/evaluation",
    pdp_application="my-agent-platform",
    client_credentials=ClientCredentialsAuth(
        token_endpoint="https://idp.example.com/oauth/token",
        client_id="agent-policy-client",
        client_secret="...",
        audience="pdp",
    ),
)
```

Tokens are cached and refreshed automatically.

### Async Backend

```python
from authzen_backend import AsyncAuthZENBackend

backend = AsyncAuthZENBackend(
    pdp_url="https://pdp.example.com/access/v1/evaluation",
    pdp_application="my-agent-platform",
    token="my-bearer-token",
)

result = await backend.evaluate({
    "tool_name": "deploy_service",
    "agent_id": "ops-agent",
})
```

### ARIA-Enhanced Context

When connected to an EmpowerNow ARIA PDP, extract rich governance context:

```python
from authzen_backend import AuthZENBackend
from authzen_backend.aria import extract_aria_context

backend = AuthZENBackend(
    pdp_url="https://aria-pdp.example.com/access/v1/evaluation",
    pdp_application="my-platform",
    token="...",
)

result = backend.evaluate({"tool_name": "transfer_funds", "agent_id": "finance-bot"})

aria = extract_aria_context(result)
print(aria.decision_id)       # Links to signed receipt
print(aria.obligations)       # Actions caller must perform
print(aria.constraints)       # Parameter-level restrictions
print(aria.advice)            # Structured denial guidance
print(aria.requires_approval) # Human-in-the-loop flag
```

## Context Mapping

The toolkit passes a flat `dict` to backends. This package maps it to a structured AuthZEN request:

| Toolkit Context Key | AuthZEN Field | Notes |
|---------------------|---------------|-------|
| `agent_id` | `subject.id` | Normalized to ARN: `auth:agent:agentmesh:{id}` |
| `user_id` | `subject.properties.bound_to_user_id` | User the agent acts for |
| `delegator` | `subject.properties.delegator` | Delegation chain |
| `tool_name` | `action.name`, `resource.id` | Also generates `op:tool:{name}` |
| `action` | `action.name` | Overrides `tool_name` if present |
| `resource_type` | `resource.type` | Defaults to `mcp_tool` |
| `resource_id` | `resource.id` | Defaults to `tool_name` |
| *(all others)* | `context.*` | Forwarded as-is |

`context.pdp_application` and `action.properties.operation_ref_id` are set automatically.

### Custom Mapping

Override field names if your agents use different context keys:

```python
from authzen_backend import AuthZENBackend, FieldMapping

backend = AuthZENBackend(
    pdp_url="https://pdp.example.com/access/v1/evaluation",
    pdp_application="my-platform",
    token="...",
    mapping=FieldMapping(
        agent_id_key="principal",
        tool_name_key="operation",
        user_id_key="end_user",
    ),
)
```

## Configuration Reference

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `pdp_url` | `str` | *(required)* | AuthZEN evaluation endpoint URL |
| `pdp_application` | `str` | *(required)* | Application ID for policy scoping |
| `token` | `str` | `None` | Static Bearer token (mutually exclusive with `client_credentials`) |
| `client_credentials` | `ClientCredentialsAuth` | `None` | OAuth client credentials config |
| `timeout` | `float` | `5.0` | HTTP timeout in seconds |
| `default_resource_type` | `str` | `"mcp_tool"` | Fallback resource type |
| `default_subject_type` | `str` | `"ai_agent"` | Fallback subject type |
| `mapping` | `FieldMapping` | `DEFAULT_MAPPING` | Context field name overrides |
| `fail_closed` | `bool` | `True` | If `True`, PDP errors yield an authoritative deny. If `False`, errors are signalled via the `error` field so the toolkit can try the next backend. |
| `http_client` | `httpx.Client` / `AsyncClient` | `None` | Inject a pre-configured HTTP client (useful for testing or connection pooling). When provided, the caller owns its lifecycle. |

## Compatibility

- **Python:** 3.10+
- **Dependencies:** `httpx`, `pydantic` (v2)
- **Agent Governance Toolkit:** `agent-os-kernel` (any version with `ExternalPolicyBackend`)
- **PDP:** Any OpenID AuthZEN 1.0 compliant PDP

This package has **zero dependency on `agent-os-kernel`** — it implements the `ExternalPolicyBackend` protocol structurally (duck typing). Install alongside the toolkit or use standalone.

## Development

```bash
git clone https://github.com/EmpowerID/authzen-policy-backend.git
cd authzen-policy-backend
pip install -e ".[dev]"
pytest tests/ -v
```

## License

MIT — see [LICENSE](LICENSE).

## Links

- [OpenID AuthZEN Specification](https://openid.net/specs/openid-authzen-authorization-api-1_0.html)
- [Microsoft Agent Governance Toolkit](https://github.com/microsoft/agent-governance-toolkit)
- [EmpowerNow ARIA White Paper](https://empowerid.com/aria)
