Observed since 20 Oct, 18:10 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Agentic Execution Protocol™ (AEP™) - trust & safety infrastructure for AI agents
AceTeam™ trust & safety infrastructure for AI agents. The Agentic Execution Protocol™ (AEP™) adds cost tracking, safety detection, and enforcement to any LLM-powered tool — zero code changes required.
The gateway runs a single process on one port with three interfaces:
| Path | What it does |
|---|---|
/v1/* | OpenAI-compatible reverse proxy with safety enforcement |
/dashboard/ | Dashboard — cost, signals, policy controls, setup wizard |
/mcp/ | MCP tools for Claude Code and any MCP client |
pip install aceteam-aep[all] # Everything (recommended)
pip install aceteam-aep[proxy,safety] # Proxy + ML detectors (PII, content safety)
pip install aceteam-aep[proxy,custom-policies] # Proxy + natural-language policies (PAW)
pip install aceteam-aep[proxy] # Lightweight proxy: regex + threshold detectors only
pip install aceteam-aep # Core: cost tracking + regex safety
The safety extra pulls in transformers + torch (ML detectors). The custom-policies
extra pulls in programasweights (natural-language policy compilation, large native build).
Both are opt-in so a default [proxy] install stays slim.
# Install and start the gateway
pip install aceteam-aep[all]
aceteam-aep proxy
The gateway prints three URLs on startup:
SafeClaw Gateway
───────────────────────────────────
LLM Proxy: http://localhost:8899/v1
Dashboard: http://localhost:8899/dashboard/
MCP: http://localhost:8899/mcp/
Open the dashboard — a setup wizard appears on first visit and walks you through pointing your agent at the proxy or configuring Claude Code.
Point an agent at the gateway:
export OPENAI_BASE_URL=http://localhost:8899/v1
export OPENAI_API_KEY=sk-your-key
openclaw run "analyze these financial statements"
Open http://localhost:8899/dashboard/ — every LLM call appears in real-time with cost, safety signals, and enforcement decisions.
The proxy intercepts both directions:
Works with OpenClaw, LangChain, CrewAI, curl, or any tool that calls the OpenAI API.
EnvelopeBuilder.end_node_cancelled(span_id, cost=...) closes a node with the
existing CANCELLED span status and an end timestamp. Use it for work aborted
before completion. It records no execution error and retains already-incurred
costs. EnvelopeBuilder.reconstruct also preserves CANCELLED node records.
Span consumers should distinguish cancellation from both OK and ERROR.
Cancellation is terminal but belongs in neither successful-work counts nor
failure alerts. Duration and cost aggregation still include the aborted work.
The caller continues to select the envelope's success, partial, or failure
status through finish(); a cancelled child alone does not establish that the
whole execution was cancelled. Whole-execution cancellation policy and run-ledger
aggregation remain the host application's responsibility.
The proxy is a reverse proxy (man-in-the-middle by design). It reads the full request AND full response. It can block in either direction.
Your Agent
│
├─── REQUEST ──────────────────────────────┐
│ messages: [user prompt, tool results] │
│ ▼
│ ┌─────────────┐
│ │ AEP Proxy │
│ │ │
│ │ ✓ Input │──── if dangerous ──→ BLOCK (never reaches API)
│ │ text │
│ │ │──── if safe ──→ forward to OpenAI
│ │ │
│ │ ✓ Output │──── if PII/toxic ──→ BLOCK (agent never sees it)
│ │ text │
│ │ │──── if safe ──→ return to agent
│ │ ✓ Cost │
│ │ ✓ Tool calls│
│ └─────────────┘
│ │
◄─── RESPONSE ─────────────────────────────┘
assistant message, token usage
| Data | Proxy Sees It? | Details |
|---|---|---|
| User messages (input text) | Yes | Full message array from request body |
| LLM response (output text) | Yes | Full response including all choices |
| Tool call requests | Yes | What functions the LLM asks to call |
| Tool call results | Yes | Included in next request's messages |
| Token usage + cost | Yes | From response usage field |
| Agent actions between calls | No | File writes, code execution, browser actions happen inside the agent, not via the LLM API |
| Application context | No | Who is calling, data classification — unless sent via X-AEP-* headers |
The proxy sees every word going to and from the LLM. It cannot see what the agent does between LLM calls. For that, use the SDK (Layer 2).
Think WireGuard + Tailscale. WireGuard is a minimal wire protocol. Tailscale adds identity and management on top. Same here:
Layer 1 — AEP Proxy (free, zero code changes)
/dashboard/Layer 2 — AEP SDK (application-level context)
X-AEP-Entity: org:acmeX-AEP-Classification: confidentialwrap()Layer 1 gets developers in the door. Layer 2 is what enterprises need for compliance.
import openai
from aceteam_aep import wrap
client = wrap(openai.OpenAI())
# Use exactly as before — AEP intercepts transparently
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
)
# AEP tracks everything
print(client.aep.cost_usd) # $0.000150
print(client.aep.enforcement.action) # "pass"
print(client.aep.safety_signals) # []
client.aep.print_summary() # Colored CLI output
Works with OpenAI, Anthropic, and any OpenAI-compatible client. Sync and async.
import anthropic
from aceteam_aep import wrap
client = wrap(anthropic.Anthropic())
# Same API — client.aep.cost_usd, client.aep.safety_signals, etc.
Every LLM call is evaluated by pluggable safety detectors:
| Detector | What It Catches | Model |
|---|---|---|
| PII | SSN, email, phone, credit cards in input AND output | iiiorg/piiranha-v1-detect-personal-information (~110M) |
| Content Safety | Toxic, harmful, or unsafe content | s-nlp/roberta_toxicity_classifier (~125M) |
| Agent Threat | Port scans, subprocess execution, reverse shells, credential access, destructive commands | Regex patterns (11 patterns) |
| Cost Anomaly | Spend spikes >5x session average | Statistical (no model) |
Models lazy-load on first use, run on CPU. PII falls back to regex if transformers not installed.
wrap() runs detectors on the input before making the API call. If a detector returns a HIGH severity signal that the enforcement policy would block, the request never reaches the LLM. Cost: $0.
from aceteam_aep import wrap, AepPreflightBlock
client = wrap(openai.OpenAI())
try:
response = client.chat.completions.create(...)
except AepPreflightBlock as e:
print(f"Blocked before API call: {e}")
# e.decision.reason has the details
client = wrap(openai.OpenAI(), policy={
"default_action": "flag",
"detectors": {
"pii": {"action": "block", "threshold": 0.8},
"agent_threat": {"action": "block"},
"cost_anomaly": {"action": "pass", "multiplier": 10},
},
})
Or from a YAML file: wrap(client, policy="aep-policy.yaml")
Every call produces an enforcement decision based on signal severity:
client = wrap(openai.OpenAI())
response = client.chat.completions.create(...)
match client.aep.enforcement.action:
case "pass":
return response
case "flag":
queue_for_review(response)
case "block":
return reject(client.aep.enforcement.reason)
from aceteam_aep import wrap
from aceteam_aep.safety.base import SafetySignal
class MyDetector:
name = "my_detector"
def check(self, *, input_text, output_text, call_id, **kwargs):
if "secret" in output_text.lower():
return [SafetySignal(
signal_type="data_leak",
severity="high",
call_id=call_id,
detail="Potential secret in output",
)]
return []
client = wrap(openai.OpenAI(), detectors=[MyDetector()])
Inject governance context via HTTP headers (any language, any framework):
curl http://localhost:8080/v1/chat/completions \
-H "X-AEP-Entity: org:acme-corp" \
-H "X-AEP-Classification: confidential" \
-H "X-AEP-Consent: gdpr=granted,training=no" \
-H "X-AEP-Budget: 5.00" \
-H "X-AEP-Trace-ID: trace-abc123"
The proxy parses these headers, strips them before forwarding to the LLM (governance context never leaks to the provider), and includes classification and trace ID in the response headers.
For containerized agents (NanoClaw, CrewAI, DeerFlow, OpenClaw, NemoClaw):
services:
aep-proxy:
image: ghcr.io/aceteam-ai/aep-proxy:latest
ports: ["8899:8899"]
environment:
OPENAI_API_KEY: ${OPENAI_API_KEY}
agent:
image: your-agent:latest
environment:
OPENAI_BASE_URL: http://aep-proxy:8899/v1
One env var. Zero code changes. The agent doesn't know AEP exists.
Tested with NVIDIA NemoClaw/OpenShell: Agent threats (port scanning, subprocess execution) blocked at the proxy before reaching the LLM. Normal calls pass through with receipts. See aep-quickstart for the full NemoClaw demo.
Add the gateway as an MCP server in your Claude Code config:
{
"mcpServers": {
"aceteam": {
"type": "streamable-http",
"url": "http://localhost:8899/mcp/"
}
}
}
This gives Claude four tools: check_safety, get_safety_status, set_safety_policy, and get_cost_summary. All tools share live state with the proxy — safety checks via MCP appear in the dashboard and affect traffic enforcement.
See docs/engineering/mcp-integration.md for full tool reference.
Two views — toggle between Developer and Executive:
Developer: Individual calls, safety signals, cost per call, governance context, call timeline.
Executive: Enforcement coverage %, threats blocked, compliance status (PII/threats/toxicity/anomalies), safety breakdown, cost attribution by entity.
Policy controls: Per-detector checkboxes and per-category Trust Engine toggles — adjust enforcement without restarting. The master safety toggle in the header disables all detectors instantly.
Setup wizard: Shows on first visit (zero calls). Guides through API key configuration and agent setup — provides the OPENAI_BASE_URL export command and Claude Code MCP config to copy.
client.aep.serve_dashboard() # http://localhost:8899
Dark-themed local web UI. Auto-refreshes every 2 seconds.
client.aep.print_summary()
──────────────────────────────────────────────────
AEP Session Summary
──────────────────────────────────────────────────
Calls: 5
Cost: $0.004200
Safety: PASS
──────────────────────────────────────────────────
For building agents from scratch with full AEP compliance:
from aceteam_aep import create_client, run_agent_loop, ChatMessage, tool
client = create_client("gpt-4o", api_key="sk-...")
@tool
def search(query: str) -> str:
"""Search for information."""
return f"Results for: {query}"
result = await run_agent_loop(
client,
[ChatMessage(role="user", content="Search for AEP protocol")],
tools=[search],
system_prompt="You are a helpful assistant.",
)
Step-by-step setup in 5 minutes — from install to safety signals firing:
Covers: proxy setup, routing agents (Python/OpenClaw/curl), triggering safety signals, governance headers, custom detectors. Works for workshops, onboarding, or self-guided evaluation.
Add this badge to your repo's README to show it uses AEP safety enforcement:
[](https://github.com/aceteam-ai/aceteam-aep)
"Agentic Execution Protocol," "AEP," and "AceTeam" are trademarks of AceTeam. The software is licensed under Elastic License 2.0. The trademark is not included in the license grant — you may not use these names to endorse or promote derivative works without written permission.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.11.9 | 26 Sept 2026 | 24 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 18:10 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:b4381d2da70b20ff1fde2bc32300a699f3781a72eb7dd4b04bbe26477a83d82c