Your agent accessed the production database when it should only read staging. Your support agent sent a refund without approval. Your code agent deleted files it was never supposed to touch.
AXME enforces action policies at the gateway level - before the intent reaches the agent. Not inside the agent. Not "trust the prompt." Actual enforcement.
Alpha - Built with AXME (AXP Intent Protocol). cloud.axme.ai - contact@axme.ai
AI agents do things they shouldn't. Every team learns this the hard way:
- Agent calls a tool it wasn't supposed to. The LLM decided
drop_tablewas the right action. Your prompt said "don't do that." The LLM didn't care. - No external enforcement. Restrictions live inside the agent's system prompt. The same LLM that decides what to do also decides whether it's allowed. That's not a security boundary.
- Different agents need different permissions. The analytics agent should read data. The deploy agent should deploy. The support agent should look up tickets. But they all have access to the same tools.
- No audit trail. When the agent does something wrong, you find out from the damage. Not from a log.
- Framework-specific. LangGraph has one permission model. CrewAI has another. OpenAI Agents SDK has
tool_choice. None of them enforce at the network level.
The root cause: agent permissions live inside the agent. The agent checks its own permissions. That's like asking the intern to enforce their own access policy.
Agent sends intent --> AXME Gateway --> Agent receives intent
|
Check action policy
(allowlist / denylist)
|
Allowed? -> deliver
Blocked? -> 403 + audit log
Policies are enforced at the gateway - outside the agent, outside the LLM, outside the framework. The agent never sees the blocked intent. There is no prompt injection that bypasses this.
Three modes:
| Mode | Behavior |
|---|---|
open |
All intent types allowed (default) |
allowlist |
Only listed intent types pass through |
denylist |
Listed intent types are blocked |
Two directions:
| Direction | What it controls |
|---|---|
send |
What intent types the agent can send |
receive |
What intent types the agent can receive |
Only allow the analytics agent to receive data-read intents:
import httpx
import os
AXME_API_KEY = os.environ["AXME_API_KEY"]
BASE_URL = "https://api.axme.ai"
# Set allowlist: agent can ONLY receive these intent types
resp = httpx.put(
f"{BASE_URL}/v1/mesh/agents/analytics-agent/policies/action",
headers={"x-api-key": AXME_API_KEY},
json={
"direction": "receive",
"mode": "allowlist",
"patterns": [
"intent.data.read.*",
"intent.data.query.*",
],
},
)
print(resp.json())
# {"ok": true, "policy_id": "pol_...", "direction": "receive",
# "mode": "allowlist", "patterns": ["intent.data.read.*", "intent.data.query.*"]}# Someone tries to send a write intent to the analytics agent
resp = httpx.post(
f"{BASE_URL}/v1/mesh/intents",
headers={"x-api-key": AXME_API_KEY},
json={
"intent_type": "intent.data.delete.v1",
"to_agent": "agent://myorg/production/analytics-agent",
"payload": {"table": "customers", "filter": "all"},
},
)
print(resp.status_code) # 403
print(resp.json())
# {
# "error": "action_policy_violation",
# "message": "Intent type 'intent.data.delete.v1' not in receive allowlist",
# "direction": "receive",
# "address_id": "analytics-agent"
# }The intent never reaches the agent. The gateway blocks it. The violation is logged in the audit trail.
Block the support agent from sending refund intents:
resp = httpx.put(
f"{BASE_URL}/v1/mesh/agents/support-agent/policies/action",
headers={"x-api-key": AXME_API_KEY},
json={
"direction": "send",
"mode": "denylist",
"patterns": [
"intent.billing.refund.*",
"intent.billing.credit.*",
"intent.account.delete.*",
],
},
)Now the support agent can send any intent except refunds, credits, and account deletions.
# Set allowlist
axme mesh policies set analytics-agent \
--direction receive \
--mode allowlist \
--patterns "intent.data.read.*,intent.data.query.*"
# View current policies
axme mesh policies get analytics-agent
# Remove policy
axme mesh policies delete analytics-agent --direction receiveView and manage action policies visually at mesh.axme.ai under the Policies tab.
- Select an agent from the mesh
- Set allowlist/denylist per direction
- See violations in the audit log
- Monitor which intents are being blocked
{
"scenario_id": "policy-enforcement.demo.v1",
"title": "Action policy enforcement demo",
"description": "Analytics agent with restricted action policy. Delete intents are blocked at the gateway.",
"agents": [
{
"role": "analyst",
"address": "analytics-agent-demo",
"display_name": "Analytics Agent",
"delivery_mode": "stream",
"create_if_missing": true
}
],
"workflow": {
"steps": [
{
"step_id": "analyze",
"tool_id": "tool.agent.task.v1",
"assigned_to": "analyst",
"step_deadline_seconds": 60
}
]
},
"intent": {
"type": "intent.data.read.v1",
"payload": {
"dataset": "sales_q1",
"query": "SELECT region, SUM(revenue) FROM sales GROUP BY region"
},
"max_delivery_attempts": 3
}
}# Apply scenario
axme scenarios apply scenario.json
# Set policy: analytics agent can only RECEIVE read/query intents
axme mesh policies set analytics-agent-demo \
--direction receive \
--mode allowlist \
--patterns "intent.data.read.*,intent.data.query.*"AXME_API_KEY=<agent-key> python agent.py# This will be blocked by the gateway - 403
axme intents send \
--type "intent.data.delete.v1" \
--to "analytics-agent-demo" \
--payload '{"table": "customers"}'
# Error: action_policy_violation - Intent type 'intent.data.delete.v1' not in receive allowlist| Prompt-based restrictions | Gateway-enforced policies | |
|---|---|---|
| Where enforced | Inside the LLM | At the network gateway |
| Prompt injection bypass | Vulnerable | Impossible |
| Agent framework dependency | Framework-specific | Framework-agnostic |
| Audit trail | None | Every violation logged |
| Change without redeploy | Edit prompt, redeploy | API call or dashboard toggle |
| Granularity | "Don't do X" (vague) | Pattern matching on intent types |
| Multi-agent consistency | Each agent configured separately | Centralized policy management |
Patterns support wildcards for flexible matching:
| Pattern | Matches |
|---|---|
intent.data.read.v1 |
Exact match only |
intent.data.read.* |
Any version of data read |
intent.data.* |
Any data intent |
intent.billing.refund.* |
Any refund intent |
AXME policies work at the transport layer. The agent framework doesn't matter.
| Framework | How it works |
|---|---|
| LangGraph | Intents blocked before reaching graph nodes |
| CrewAI | Crew tasks gated by policy |
| AutoGen | Cross-agent messages filtered at gateway |
| OpenAI Agents SDK | Tool call intents blocked externally |
| Google ADK | Action restrictions independent of ADK config |
| Pydantic AI | Policy enforcement where Pydantic AI has none |
| Any language | HTTP API - works from Python, TypeScript, Go, Java, .NET |
- AXME - project overview
- AXP Spec - open Intent Protocol specification
- AXME Examples - 20+ runnable examples across 5 languages
- AXME CLI - manage intents, agents, scenarios from the terminal
- AI Agent Kill Switch - emergency stop for AI agents
- AI Agent Cost Monitoring - budget limits and cost tracking
Built with AXME (AXP Intent Protocol).

