Skip to content

About

Runtime action firewall for AI agents: the keyless Shield. Screens catastrophic tool calls (DROP TABLE, SSRF, secret exfil) in-process, no key. Watches by default; set the posture to enforce to block. MIT.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Latest commit

 

History

28 Commits

Folders and files

Repository files navigation

🛡️ AgentX SDK: The Action Firewall for AI Agents

PyPI Python 3.8+ License: MIT

LLM agents are powerful and brittle. Given the wrong prompt they will drop a production table, read a secret, or POST your data to an attacker's URL. A traditional guardrail answers with a hard 403 that kills the run and burns the tokens you already spent.

AgentX is different, and it protects you with zero keys. The hero is a deterministic Shield that runs in-process, screening every call against a floor that needs no LLM and no network: DROP TABLE, SSRF, secret reads, destructive shell and cloud teardown. Out of the box it watches and records what it finds and blocks nothing. Set AGENTX_POSTURE=enforce, or pin a single tool with posture="enforce", and the same floor stops those calls before they run and hands your agent coaching to self-correct on. It escalates the consequential-but-legitimate ones (large transfers, external publishes, runaway spend, bulk deletes) for a human to approve. No API key, no signup, no LLM round-trip.

This repository is the MIT-licensed SDK: the keyless Shield, which you can read, audit, and run yourself with no AgentX account.

Install

pip install agentx-security-sdk

See it work in 10 seconds (no key, no gateway)

agentx demo

Runs a canned agent that attempts a DROP TABLE and lets you watch the in-process Shield block it offline. It is the fastest way to confirm the install before you wire it into your own agent.

Caught something you are proud of? Turn it into a shareable card:

agentx share

agentx share renders your most recent catch as a screenshot-able receipt. It is privacy-safe by construction: it uses the policy class and your own tool name only, never the query or the payload.

Protect a tool

Add @agentx_protect over any high-risk tool. The SDK inspects the call at runtime, so there is no schema to write and no boilerplate:

from agentx_sdk.decorators import agentx_protect

@agentx_protect(agent_id="crm_worker")
def run_sql(query: str, db=None):
    ...

That wrap watches and records every call it sees. To have it stop a flagged one, export AGENTX_POSTURE=enforce for the whole process, or pin the single tool with @agentx_protect(agent_id="crm_worker", posture="enforce"). A pinned tool keeps that posture until you delete the argument, and it wins over the environment variable.

Once blocking is on, your code reacts with is_block(). You never parse message text, you read structured fields:

from agentx_sdk import agentx_protect, is_block

result = run_sql(query=untrusted)

if is_block(result):
    print(f"Blocked by policy: {result.policy}")
    llm.send(result.challenge)   # feed the safe-path challenge back so the agent self-corrects
else:
    use(result)                  # not blocked: the real return value

For strictly-typed tools (LangChain or Pydantic tools that validate a -> dict return), AgentX raises instead of returning, so the framework does not crash on a changed return type:

from agentx_sdk import AgentXSecurityBlock

try:
    data = fetch_user(uid)       # -> dict
except AgentXSecurityBlock as block:
    llm.send(block.challenge)

The statement has to reach the Shield in an argument named for what it is. query, sql, statement, command, path and url are read as what they say they are, as is the single string argument of a tool whose own name says what it runs. Free text is not: a note or a body carrying the same words is recorded and left alone, so a ticket that happens to say "update the cart set aside for later" is not treated as a mass write.

A runaway-loop circuit-breaker trip is not a policy block. It raises AgentXCircuitBreakerTripped, and is_block() returns False for it, so you can catch it separately to abort the run.

Protect an MCP server with zero code

Do not own the tool's Python, or running a non-Python agent? Wrap any MCP server with agentx-mcp and every tools/call is screened by the same keyless Shield before it runs. It is one line in your mcp.json (Claude Code, Cursor, or any MCP client):

{
  "mcpServers": {
    "filesystem": {
      "command": "agentx-mcp",
      "args": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/data"]
    }
  }
}

No Python in your stack? Run it on demand with uvx so mcp.json stays one line:

{
  "mcpServers": {
    "filesystem": {
      "command": "uvx",
      "args": ["agentx-mcp", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/data"]
    }
  }
}

(pipx run agentx-mcp <real server command> works the same way.) A blocked call comes back to the agent as a coaching tool error it can self-correct on, so the run keeps going and the dangerous call never reaches the server.

Read what your agent did

Every wrapped call is written down locally, whether blocking is on or off. From the folder your agent ran in:

agentx audit             # grouped by tool: which tools ran, how often, what each touched
agentx audit --calls     # one row per call, newest first
agentx audit --json      # the same data for a program

In CI, two flags turn the screen into a verdict: agentx audit --require-calls exits 2 when the record holds no calls, so a job where the agent never ran cannot pass as a clean audit; --fail-on-rule-match exits 3 when a recorded call matched a rule you adopted.

Your own rules come from your own record: agentx review walks what got caught and lets you adopt a rule from it, into .agentx/rules.json, a file you can commit and review in a pull request. A call that matches one is marked on the audit screen and named under it. It is recorded, never blocked, in any posture.

Runnable examples

examples/ holds one script per behaviour, each small enough to read in a sitting. They live in the published sdist but not in the wheel, so pip install alone does not put them on your disk. This repository is where you read or clone them.

git clone https://github.com/vdalal/agentx-security-sdk
cd agentx-security-sdk
pip install agentx-security-sdk
python examples/00_quickstart_pip.py

00_quickstart_pip.py needs nothing beyond the SDK itself. A prompt-injected DROP TABLE reaches a protected tool and is stopped in-process, with no key and no network call. It pins posture="enforce" on the tool so you can watch the block happen, and says so in a comment; your own fresh install watches until you ask it to block.

The other scripts load a local .env for convenience, so install their extras first:

pip install -r examples/requirements.txt

examples/README.md lists what each script demonstrates and what it needs to run. Several of the later ones drive the hosted gateway and require a key, which that table marks.

What is open, and what is hosted

This repo is the keyless Shield: a deterministic in-process floor with in-band coaching, MIT-licensed, no account required. It watches by default and stops the catastrophic call once you turn blocking on, and that is the whole story for keeping it from executing.

The Recover tier turns a block into a completed task. When you connect the hosted gateway, the agent gets a task-fitting path back and finishes the run instead of crashing, with human-in-the-loop review on the consequential calls. Recover runs in the hosted gateway, not in this SDK. Request access at agentx-core.com.

Development

pip install -e .

This repository is a snapshot of exactly what pip install agentx-security-sdk publishes, so it carries shipping code and examples only. The test suite is not part of the published package and is not mirrored here.

License

MIT. See LICENSE.

Homepage: agentx-core.com

About

Runtime action firewall for AI agents: the keyless Shield. Screens catastrophic tool calls (DROP TABLE, SSRF, secret exfil) in-process, no key. Watches by default; set the posture to enforce to block. MIT.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages