Skip to main content

Regent Control — Python SDK

Runtime policy enforcement for AI agent actions. Every action your agent takes — a refund, a wire, a DB write, an API call — is authorized first: allow / deny / escalate, with a short-lived scoped token, the human it's acting for, the intent, and an immutable audit record.

pip install regent-control

Requires Python 3.10+. The only dependency is httpx.

Two ways to integrate

1. Gate-direct — RegentControl (you hold the provider key)

Authorize the action, get a scoped token, perform it, report the outcome.

from regent_control import RegentControl, MandateExceeded, Escalated

control = RegentControl(api_key="rgnt_ctrl_…", agent_id="agent_refund_bot")

decision = control.authorize(
    tool="payments", action="refund.create",
    amount_usd=50, mandate_id="mnd_support_refunds",
    idempotency_key="T-8842:ch_aaa",          # a retry won't double-refund
    user_token=rep_id_token,                  # the rep's OIDC token — verified by the gate
    intent="refund the duplicate charge on ticket 8842",
    facts={"account_status": "active", "refund_to_original": True},
)

if not decision.allowed:
    ...                                        # decision.code / decision.reason
do_refund(scoped_token=decision.token)         # the token authorizes the downstream call
control.complete(decision.decision_id, status="success", downstream_ref=refund_id)

A deny is a normal return value, not an exception. Opt into raising:

decision.raise_for_status()                    # raises MandateExceeded / PolicyDenied / Escalated / …
# or
control.authorize_or_raise(tool="payments", action="refund.create", amount_usd=999)

2. Sidecar-routing — SidecarSession (the agent holds no key)

Point your normal HTTP call at the sidecar; it injects the real vaulted credential and forwards. A policy deny comes back as a typed error.

from regent_control import SidecarSession, MandateExceeded

sc = SidecarSession(base_url="http://localhost:8080",
                    user_token=rep_id_token, intent="refund duplicate charge")
try:
    resp = sc.call("payments", "refunds", method="POST",
                   json={"charge": "ch_aaa", "amount": 50},
                   facts={"account_status": "active", "refund_to_original": True},
                   idempotency_key="T-8842:ch_aaa")
    refund = resp.json()
except MandateExceeded as e:
    ...                                        # e.code, e.reason, e.decision_id

Both clients have async twins: AsyncRegentControl and AsyncSidecarSession.

Wrap a tool in one line — @guarded

from regent_control import RegentControl, guarded

control = RegentControl(api_key="rgnt_ctrl_…", agent_id="agent_refund_bot")

@guarded(control, tool="payments", action="refund.create",
         amount_arg="amount_usd", mandate_id="mnd_support_refunds")
def issue_refund(*, charge: str, amount_usd: float, scoped_token: str = "") -> str:
    return provider.refund(charge, amount_usd, token=scoped_token)

issue_refund(charge="ch_1", amount_usd=50)     # authorized → runs → completed
issue_refund(charge="ch_1", amount_usd=999)    # raises MandateExceeded; never runs

The decorator authorizes before the call, injects the scoped token (if the function declares scoped_token), and reports success/failed to close the audit. Pass per-call context via a control_context={...} keyword.

Verify the scoped token at your service edge — regent_control.verify

The complement to the client: your downstream service validates the gate-issued scoped JWT against Regent's JWKS and enforces the scope itself (least privilege at the edge — no shared static key, no trusting the caller).

pip install "regent-control[verify]"   # adds PyJWT
from regent_control.verify import TokenVerifier, ScopeError

verifier = TokenVerifier(jwks_url="https://control-api.regentprotocol.org/v1/control/.well-known/jwks.json")
scoped = verifier.verify(token, expected_tool="payments", expected_action="refund.create")
# raises TokenError (bad sig / expired / wrong issuer|audience) or ScopeError (wrong scope)
# scoped.agent_id / scoped.decision_id are audit-ready

See examples/verify_service.py for a FastAPI dependency.

Develop locally with zero prod — regent-control dev

regent-control dev --port 8009 --deny-over 50 --escalate-over 500
# point any client at  base_url="http://localhost:8009"

In tests, force a verdict with the in-process mock:

from regent_control import RegentControl, MandateExceeded
from regent_control.dev import run_mock_control

def test_over_limit_is_denied():
    with run_mock_control(deny_over=50) as base_url:
        control = RegentControl(api_key="dev", agent_id="a", base_url=base_url)
        d = control.authorize("stripe", "refund.create", amount_usd=999)
        assert d.code == "MANDATE_LIMIT_EXCEEDED"

Typed errors

Exception Decision code Meaning
IdentityNotResolved IDENTITY_NOT_RESOLVED the agent id didn't resolve
AgentNotActive AGENT_NOT_ACTIVE the agent is suspended/revoked
PolicyDenied POLICY_DENIED a policy rule forbade it
ToolNotAllowed TOOL_NOT_ALLOWED the tool isn't in the agent's catalog
MandateNotFound MANDATE_NOT_FOUND a money action with no mandate
MandateExceeded MANDATE_LIMIT_EXCEEDED over the spend cap
RiskThresholdExceeded RISK_THRESHOLD_EXCEEDED risk score too high
VelocityExceeded VELOCITY_EXCEEDED too many decisions for this agent in the window; back off
DuplicateRequest DUPLICATE_REQUEST an identical money request was just allowed; pass an idempotency_key for a deliberate repeat
Escalated ESCALATION_REQUIRED needs a human approval (carries .escalation)

ControlError (transport/auth/5xx) and ControlNetworkError (never reached the plane) are always raised; everything above subclasses ControlDenied.

Request signing (optional)

Pass sign_requests=True to HMAC-sign the request body with the per-agent secret HMAC-SHA256(api_key, agent_id) (X-Agent-Signature). Identical to @regent/control-sdk (TypeScript), so an agent moves between the two unchanged.

Examples

Metadata

Release files for regent-control 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 regent-control 0.1.0
File Size Uploaded
regent_control-0.1.0.tar.gz 26.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for regent-control 0.1.0
File Interpreter ABI Platform
regent_control-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 53.4 kB

Release files / regent_control-0.1.0.tar.gz

Download URL regent_control-0.1.0.tar.gz
Size 26.5 kB
Tags Source
SHA-256 checksum
How to use checksums
d641dbbf96d1d7009861fef823fded2c3c676796da3bdf186837dbdf740eb96c
BLAKE2b-256 checksum
How to use checksums
65db16be887c727eda73b8323dc3945e1e31811fc1550061331645e92f730ed3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

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

Download URL regent_control-0.1.0-py3-none-any.whl
Size 26.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f0f26a1f74205c83d511cbb16702b7a8a71d9944331fa6ae13a29568254b02d6
BLAKE2b-256 checksum
How to use checksums
2db66bf33ef6dad8bd2b43cd415ca73b4dd009dd9202aae3acb7eb6120e0dcb1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.0

2 release files

0.2.0

2 release files

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