Skip to main content

Framework-agnostic authorization middleware for AI agents

Project description

Xybern agent-guard

xybern-agent-guard

Framework-agnostic authorization middleware for AI agents.

Intercept, inspect, and enforce policies on any agent action before it executes, whether you're using LangChain, OpenAI, Anthropic, or a bare Python function.

Get an API key — email info@xybern.com to connect to the Xybern authorisation backend. Free to start.

from agent_guard import Guard
from agent_guard.backends import StubBackend

guard = Guard(backend=StubBackend().block(["delete_*", "drop_table"]))

@guard.intercept("send_email")
def send_email(to, subject, body):
    ...  # only runs if the action is allowed

Why

AI agents make real-world calls, they write to databases, send emails, execute trades, call APIs. Without a policy layer between the agent's decision and the actual execution, there's no safety net.

agent-guard sits at that boundary. Every action goes through a check() before it runs. The backend decides: allow, block, or escalate. Your code doesn't change, just wrap it.


Get an API key

To use the Xybern authorisation backend in production, email info@xybern.com to get an API key. The StubBackend works out of the box for local development and testing with no key required.


Install

pip install xybern-agent-guard

No required dependencies. Zero. The core library uses only the Python standard library.

Optional extras for framework adapters:

pip install xybern-agent-guard[langchain]
pip install xybern-agent-guard[openai]
pip install xybern-agent-guard[anthropic]
pip install xybern-agent-guard[all]

Quick start

Decorator

from agent_guard import Guard
from agent_guard.backends import StubBackend

guard = Guard(backend=StubBackend(default="allow").block(["delete_*"]))

@guard.intercept("write_file")
def write_file(path, content):
    with open(path, "w") as f:
        f.write(content)

@guard.intercept("delete_file")
def delete_file(path):
    os.remove(path)  # never reached — PolicyBlockedError is raised first

Context manager

with guard.protect("database_write", content=query):
    db.execute(query)

Manual check

decision = guard.check("execute_trade", content="Buy 1000 AAPL at market")
if decision.allowed:
    execute_trade(...)

Async

@guard.intercept("send_notification")
async def send_notification(user_id, message):
    await notify(user_id, message)

# or
decision = await guard.check_async("send_notification", content=message)

# or
async with guard.protect_async("write_cache", content=key):
    await cache.set(key, value)

Backends

Backends decide what happens when an action is checked. Swap them out without changing application code.

StubBackend - local, no external calls

from agent_guard.backends import StubBackend

backend = (
    StubBackend(default="allow")           # allow everything by default
    .block(["delete_*", "drop_table"])     # block these patterns
    .escalate(["send_email", "wire_*"])    # escalate these patterns
    .allow(["read_*"])                     # explicitly allow these
)

Patterns support wildcards (*). Rules are evaluated in order — first match wins.

HttpBackend — any HTTP endpoint

from agent_guard.backends import HttpBackend

backend = HttpBackend(
    url="https://your-policy-server.com/evaluate",
    headers={"Authorization": "Bearer your-token"},
    timeout=5,
)

POST body: serialized Action. Expected response: {"outcome": "allow"|"block"|"escalate", "reason": "..."}.

XybernBackend — Xybern Authorisation API

from agent_guard.backends import XybernBackend

backend = XybernBackend(
    api_key="xb_live_...",
    workspace_id="ws_...",   # optional
)

Routes every action through the Xybern Authorisation layer. Gives you audit logs, escalation workflows, policy management UI, and trust scoring out of the box.

Build your own

from agent_guard.backends import Backend
from agent_guard.types import Action, Decision

class MyBackend(Backend):
    def evaluate(self, action: Action) -> Decision:
        # your logic here
        if action.action_type.startswith("delete"):
            return Decision(outcome="block", reason="deletes are not permitted")
        return Decision(outcome="allow")

Framework adapters

LangChain

from agent_guard.adapters.langchain import guard_tools

tools = guard_tools([search_tool, calculator_tool, email_tool], guard=guard)
agent = create_react_agent(llm, tools, prompt)

Or wrap a single tool:

from agent_guard.adapters.langchain import GuardedTool

safe_tool = GuardedTool.wrap(email_tool, guard=guard, action_type="send_email")

OpenAI

from agent_guard.adapters.openai import dispatch_tool_calls

response = client.chat.completions.create(model="gpt-4o", messages=messages, tools=tools)

tool_results = dispatch_tool_calls(
    response.choices[0].message.tool_calls,
    handlers={"get_weather": get_weather, "send_email": send_email},
    guard=guard,
)

Anthropic

from agent_guard.adapters.anthropic import dispatch_tool_use

response = client.messages.create(model="claude-opus-4-7", messages=messages, tools=tools)

tool_results = dispatch_tool_use(
    response.content,
    handlers={"web_search": search, "send_email": send_email},
    guard=guard,
)

Configuration

Guard(
    backend=...,
    on_block="raise",     # "raise" (default) | "log" | "ignore"
    on_escalate="raise",  # "raise" (default) | "log" | "ignore"
    agent_id="my-agent",  # passed to the backend with every action
)
on_block / on_escalate behaviour
"raise" raises PolicyBlockedError / PolicyEscalatedError
"log" logs a warning, returns the Decision, execution continues
"ignore" silently returns the Decision, execution continues

Exceptions

from agent_guard import PolicyBlockedError, PolicyEscalatedError, BackendError

try:
    result = execute_trade(symbol="AAPL", qty=1000)
except PolicyBlockedError as e:
    print(e.action.action_type)   # "execute_trade"
    print(e.decision.reason)      # reason from the backend
except PolicyEscalatedError as e:
    notify_human_reviewer(e.action, e.decision)
except BackendError as e:
    # backend unreachable or returned unexpected response
    log_and_fail_safe(e)

Running tests

pip install -e ".[dev]"
pytest

Contributing

PRs welcome. Open an issue first for anything beyond small fixes.


License

MIT — see LICENSE.


Built by Xybern — regulated AI infrastructure.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

xybern_agent_guard-0.1.3.tar.gz (181.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

xybern_agent_guard-0.1.3-py3-none-any.whl (15.3 kB view details)

Uploaded Python 3

File details

Details for the file xybern_agent_guard-0.1.3.tar.gz.

File metadata

  • Download URL: xybern_agent_guard-0.1.3.tar.gz
  • Upload date:
  • Size: 181.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for xybern_agent_guard-0.1.3.tar.gz
Algorithm Hash digest
SHA256 b9134cd909e1f368564dfe211185c7e25b464392110c629d9d5c24945b7f0bf6
MD5 f4a824f98d95745a5a117583ec724de8
BLAKE2b-256 5e3a5b24f4a83441efa410ccba71c5766709fc2152879c71b7d633bd535ead74

See more details on using hashes here.

File details

Details for the file xybern_agent_guard-0.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for xybern_agent_guard-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 43c05ac6f0c64865a6baef84f265980401084e486feb2ed514960c1425905ee3
MD5 78a96c693fa8c528b99e96fa28705fb9
BLAKE2b-256 0ce5544d5e9b946f9dda8c68584c66c430e2d1632b5a7eab4611883530932e94

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page