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.

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 enforcement 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 — Authorisation enforcement 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.2.tar.gz (181.7 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.2-py3-none-any.whl (15.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: xybern_agent_guard-0.1.2.tar.gz
  • Upload date:
  • Size: 181.7 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.2.tar.gz
Algorithm Hash digest
SHA256 8ba58cc881fd0b39d796d7c997f45fce2bc45407ba95aa899dff7d34974435d9
MD5 1a3192fd006ccd1af76efaebe804afba
BLAKE2b-256 34a01c7fc48b6298648d9fc03b3ed00cd5c956a7b228105f6f1699c18190cb4c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for xybern_agent_guard-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 511b9259dcb963036b09054ac8334d4d6c2b844bceab7fb68d5752e3457487a4
MD5 f2d412dbe38b29730144e706d0f4075e
BLAKE2b-256 9b5c12359ab4db32c2b2d0e6f71aab430107bf8b492e939bddc470762ccd6c42

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