Skip to main content

AXG — Agent Execution Guard

AXG

CI PyPI - axg PyPI - axg-python-sdk npm - axg-node-sdk License: Apache-2.0 Python 3.11+

Deterministic, auditable control over what AI agents are allowed to do.

AI suggests. AXG decides.

An agent proposes an action (write a record, run a shell command, call a tool). Before anything executes, AXG evaluates it against a declarative policy and answers ALLOW, SUGGEST, CONFIRM or BLOCK. An ALLOW comes with a signed Passport that binds the decision to the exact payload, so the system that executes the action can verify it was authorized and was not changed on the way.

  • Deterministic: the same request under the same policy always gets the same decision. No model sits in the decision path.
  • Framework-agnostic: any agent, orchestrator, MCP client or backend calls one HTTP API, or embeds the engine in process.
  • Verifiable: RS256 Passports with payload hashing, JWKS and single-use jti; SDKs for Python and Node.
  • Auditable: hash-chained audit log and OpenTelemetry traces for every decision.

Contents

How it works

flowchart LR
    P["Agent, orchestrator or tool<br/>(any framework, any model)"] -->|DecisionRequest| AXG{{AXG}}
    AXG -->|ALLOW + Passport| X["Executor verifies the Passport,<br/>then acts"]
    AXG -->|SUGGEST / CONFIRM| H[Human in the loop]
    AXG -->|BLOCK| D[Denied]
    AXG -.->|spans + metrics| O[(OpenTelemetry)]
    AXG -.->|hash-chained records| A[(Audit log)]
  1. The caller authenticates with an API key and sends a DecisionRequest: who acts (agent and permissions), what it wants to do (action_type, payload) and how sure the proposer is (llm.confidence).
  2. AXG loads the policy plugin, evaluates its rules, enforces agent permissions and computes risk, confidence and uncertainty scores. The strictest outcome wins.
  3. ALLOW responses carry a Passport. The executor verifies it with an SDK before acting. Everything else carries a human-readable reason and machine-readable audit flags.

AXG never calls a model and never executes the action itself. It is not an LLM wrapper, a prompt framework or an agent framework.

Quickstart

Run the server with an API key for your app:

export AXG_KEY=$(openssl rand -hex 32)
export AXG_CLIENTS="[{\"client_id\":\"quickstart\",\"key_sha256\":\"$(python3 -c "import hashlib,os;print(hashlib.sha256(os.environ['AXG_KEY'].encode()).hexdigest())")\",\"app_ids\":[\"*\"],\"permissions\":[\"*\"]}]"

docker run --rm -p 8090:8090 -e AXG_CLIENTS="$AXG_CLIENTS" ghcr.io/pinheirodps/axg:latest

Ask for decisions (from a clone of this repository, which provides the example requests):

# A coding agent wants to read a file: ALLOW, with a Passport
curl -s localhost:8090/v1/decisions -H "Authorization: Bearer $AXG_KEY" \
  -H "Content-Type: application/json" -d @examples/allow.json

# The same agent wants to run `rm -rf /`: BLOCK
curl -s localhost:8090/v1/decisions -H "Authorization: Bearer $AXG_KEY" \
  -H "Content-Type: application/json" -d @examples/block.json
{
  "decision": "BLOCK",
  "plugin_version": "claude-code@0.1.0",
  "reason": "This command can irreversibly destroy files or devices.",
  "rules_triggered": [{"id": "destructive_shell_command", "decision": "BLOCK", "reason": "..."}],
  "scores": {"risk_score": 1.0, "risk_level": "high", "final_confidence": 0.49},
  "passport": null
}

Or install from PyPI and embed the engine in a Python process (or run the CLI directly):

pip install axg              # core engine, HTTP API and CLI (use "axg[otel]" for OpenTelemetry export)
pip install axg-python-sdk   # verify Passports and exchange approval tickets in Python
npm install axg-node-sdk     # verify Passports and exchange approval tickets in Node.js / TypeScript
import asyncio
from pathlib import Path

from axg import DecisionEngine, DecisionRequest
from axg.plugin_loader import PluginLoader

engine = DecisionEngine(loader=PluginLoader(Path("plugins")))

async def main():
    decision = await engine.decide(DecisionRequest(
        execution_id="exec-1", tenant_id="acme", app_id="claude-code", plugin_id="claude-code",
        source="coding_agent", action_type="Bash", payload={"command": "git push --force origin main"},
        llm={"confidence": 0.92},
    ))
    print(decision.decision.value, "-", decision.reason)
    # CONFIRM - This Git operation can discard work or rewrite shared history.

asyncio.run(main())

Integrations

Where your agents run Integration
Any language or framework HTTP API, plus the Python and Node SDKs to verify Passports
MCP servers and tools verify_mcp_tool_call / verifyMcpToolCall: a tool checks that AXG authorized exactly the call it received
Any MCP server (Streamable HTTP) MCP gateway: a proxy that decides every tools/call, including human approvals
AWS Bedrock AgentCore Gateway REQUEST interceptor (Lambda) that decides before Cedar
Microsoft Agent Governance Toolkit IExternalPolicyBackend for .NET
Claude Code PreToolUse hook with a policy for shell and file tools
ticket2pr (Jira ticket → pull requests) Guide and a least-privilege policy for its headless Claude Code agent
Observability OpenTelemetry traces and metrics over OTLP

Example policies live in plugins/: budget_guard (AI spend), claude-code (coding agents), ticket2pr (a headless coding agent driven from Jira tickets), finnorte (personal finance writes) and pocket_lawyer (legal assistant). Write your own with the policy guide.

Decisions

Decision Meaning Passport
ALLOW Safe to execute automatically Yes, for authenticated callers outside shadow mode
SUGGEST Show as a recommendation; do not execute silently After human approval
CONFIRM A human must confirm before execution After human approval
BLOCK Denied by policy or missing permission No

Precedence is BLOCK > CONFIRM > SUGGEST > ALLOW: the strictest applicable outcome wins. CONFIRM and SUGGEST carry a signed approval ticket: the right person approves, and AXG exchanges the ticket for a single-use Passport, with no state kept in AXG (human approvals). Errors never fail open: a policy that cannot be loaded, or a Passport that cannot be signed, results in CONFIRM. See how AXG decides.

Security

  • Authenticated callers. API keys, stored as SHA-256, bind each caller to the apps it may request decisions for and cap the permissions it may grant its agents. Anonymous callers are rejected (401) or, in migration mode, can never receive ALLOW.
  • Passport v2. A short-lived RS256 JWT with jti, nbf, tenant, caller (azp), policy version and a canonical hash of the whole actionable payload. Keys are published as JWKS, with rotation.
  • Hardening. Request size limits, per-caller rate limits, no dynamic code in policies, allow-listed remote policies, a hash-chained audit log, pinned dependencies and actions, SBOM and provenance on images.

Read the security model before exposing AXG outside a private network. Report vulnerabilities privately as described in SECURITY.md.

Documentation

Topic
Concepts Decision flow, scores, uncertainty gate, fail-safe principles
Writing policies Plugin format, rules and operators, permissions, validation
Human approvals Approval tickets, who approves, exchanging a ticket for a Passport
Signed context Facts vouched for by trusted services, so rules do not depend on the caller's word
Passport Claims, verification in Python and Node, replay protection, key rotation, MCP
API and contracts Endpoints, request and response fields, errors, JSON Schemas
Configuration and deployment Environment variables, Docker, production checklist
Security model Trust boundaries and threat model
Observability OpenTelemetry spans, events and metrics
Changelog Release notes

Status and roadmap

AXG is beta (v0.4.1) and runs in production. Packages are published on PyPI (axg, axg-python-sdk) and npm (axg-node-sdk) with provenance attestations, and multi-arch container images ship at ghcr.io/pinheirodps/axg. The API may change before 1.0; breaking changes are versioned in the contracts and listed in the changelog.

Contributing

Contributions are welcome. Start with CONTRIBUTING.md and the code of conduct. CI requires at least 98% test coverage of the core and integrations.

pip install -e ".[otel,test]"
python -m pytest --cov=axg --cov=integrations --cov-fail-under=98
python -m uvicorn axg.api:app --reload --port 8090

License

Apache-2.0

Metadata

Release files for axg 0.4.1

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

Source distribution (sdist)

Source distribution for axg 0.4.1
File Size Uploaded Provenance Actions
axg-0.4.1.tar.gz 86.2 kB With provenance Details for axg-0.4.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for axg 0.4.1
File Interpreter ABI Platform Actions
axg-0.4.1-py3-none-any.whl Python 3 none any Details for axg-0.4.1-py3-none-any.whl

Total release size: 134.1 kB

Release files / axg-0.4.1.tar.gz

Download URL axg-0.4.1.tar.gz
Size 86.2 kB
Tags Source
SHA-256 checksum
How to use checksums
42250f1bafe84dd7b86a4843203cdf3f1a4ee5f64e3f6baddf0966e6c1af1689
BLAKE2b-256 checksum
How to use checksums
057d2b266d672f48f5c310d336bd4e5461146dca2251bfa21aa6fae96ae8b4b5
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 24, 2026.

Transparency log

Release files / axg-0.4.1-py3-none-any.whl

Download URL axg-0.4.1-py3-none-any.whl
Size 47.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
966faa272bdae09b799f41fab520fa91d17f03eef81705e789c4a78d62bb6ae9
BLAKE2b-256 checksum
How to use checksums
e7507baed029f2e2d24e4b99d5669458bd578c424767fed669492db339417383
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 24, 2026.

Transparency log

Security for axg 0.4.1

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for axg-0.4.1.tar.gz

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 24, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.4.1 This release

2 release files Full provenance

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