Skip to main content

ACR Python SDK

Python client for Agent Capability Runtime — runtime-enforced capability permissions for AI agents.

Python 3.10+ License: MIT

Install

From source (PyPI publish pending):

cd Agent_Capability_Runtime/packages/sdk-python
pip install -e ".[dev]"

When published:

pip install acr-sdk

Quick Start

Embedded mode — zero infrastructure

No gateway, no Docker, no Node. Policy enforcement runs inside your process:

from acr import LocalAcrClient, can

client = LocalAcrClient()  # in-process runtime

grant = client.grant_sync(
    can("gmail.send").only_domain("company.com").limit(5).to_grant_input(agent_id="a1")
)

result = client.execute_sync(
    token=grant.token, tool="gmail.send",
    payload={"to": "user@company.com", "subject": "Hello"},
)
print(result.decision)  # "ALLOW"

result = client.execute_sync(
    token=grant.token, tool="gmail.send",
    payload={"to": "attacker@gmail.com", "subject": "Exfil"},
)
print(result.decision)  # "DENY"

Or let the environment decide (gateway when ACR_GATEWAY_URL is set, embedded otherwise):

from acr import create_client

client = create_client()

Async (FastAPI / LangChain) — gateway mode

from acr import AcrClient, can

async with AcrClient(base_url="http://localhost:3000") as client:
    # Grant a scoped capability
    grant = await client.grant(
        can("gmail.send")
        .only_domain("company.com")
        .limit(5)
        .expires_in("10m")
        .to_grant_input(agent_id="support_agent")
    )

    # Execute — ALLOW (internal domain)
    result = await client.execute(
        token=grant.token,
        tool="gmail.send",
        payload={"to": "user@company.com", "subject": "Hello"},
    )
    print(result.decision)  # "ALLOW"

    # Execute — DENY (external domain blocked)
    result = await client.execute(
        token=grant.token,
        tool="gmail.send",
        payload={"to": "attacker@gmail.com", "subject": "Exfil"},
    )
    print(result.decision)  # "DENY"

Sync

from acr import AcrClient, can

client = AcrClient(base_url="http://localhost:3000")

grant = client.grant_sync(
    can("gmail.send")
    .only_domain("company.com")
    .to_grant_input(agent_id="agent_1")
)

result = client.execute_sync(
    token=grant.token,
    tool="gmail.send",
    payload={"to": "user@company.com", "subject": "Hello"},
)
client.close()

Fluent DSL

The can() builder mirrors the TypeScript DSL:

from acr import can

# Email constraints
can("gmail.send").only_domain("company.com").limit(5).no_attachments()

# HTTP constraints
can("http.request").where(method.in_(["GET", "POST"])).where(url.in_(["https://api.example.com"]))

# Spending limit with approval
can("gmail.send").max_spend(100_00).require_approval()

# Intent-based governance
can("gmail.send").when_intent("customer_support").when_intent_action("support", "reply")

# Time-based
can("gmail.send").allowed_hours(9, 17)

Full API

Method Async Sync
Grant capability client.grant(input) client.grant_sync(input)
Execute tool client.execute(...) client.execute_sync(...)
Delegate capability client.delegate(parent_token, input) client.delegate_sync(...)
Revoke capability client.revoke(capability_id) client.revoke_sync(...)
List approvals client.list_approvals() client.list_approvals_sync()
Approve client.approve(approval_id) client.approve_sync(...)
Reject client.reject(approval_id) client.reject_sync(...)
Audit log client.list_audit() client.list_audit_sync()
Verify audit chain client.verify_audit_chain() client.verify_audit_chain_sync()
Health check client.health() client.health_sync()

Admin Authentication

client = AcrClient(
    base_url="http://localhost:3000",
    admin_api_key="your-admin-secret",
)

LangChain integration

pip install "acr-sdk[langchain]"
from acr import can
from acr.langchain import protect

tools = protect(my_tools, agent_id="my_agent", policy=can("http.request").limit(50))

See packages/integrations/langchain.

Requirements

  • Python 3.10+
  • Embedded mode: nothing else
  • Gateway mode: a running ACR gateway (pnpm dev:gateway)

Gateway e2e

With the gateway running:

python packages/sdk-python/examples/demo_wow.py   # deny / approval / revoke narrative
python packages/sdk-python/examples/e2e_gateway.py
# or
ACR_RUN_E2E=1 pytest packages/sdk-python/tests/test_e2e_gateway.py -v

License

MIT — see LICENSE

Release files for acr-sdk 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for acr-sdk 0.1.0
File Size Uploaded
acr_sdk-0.1.0.tar.gz 24.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for acr-sdk 0.1.0
File Interpreter ABI Platform
acr_sdk-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 43.2 kB

Release files / acr_sdk-0.1.0.tar.gz

Download URL acr_sdk-0.1.0.tar.gz
Size 24.2 kB
Tags Source
SHA-256 checksum
How to use checksums
420775517b1edcaf9d3a5242f546ed112824c42d3da84a60c335ca4e35f91623
BLAKE2b-256 checksum
How to use checksums
74aecfc124a5f520617e54016264eb5186b159824d88978e4e8429a9403c848b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.4

Release files / acr_sdk-0.1.0-py3-none-any.whl

Download URL acr_sdk-0.1.0-py3-none-any.whl
Size 19.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b34e66f2cb0c8fcee5590a7e0bb4d5a68d3478764b393df770bb58426265d685
BLAKE2b-256 checksum
How to use checksums
b58560fffa8d4351f0e56c400c224012439dcc04f192d402830073ff75fe21f8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.4

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page