Skip to content

AxmeAI/ai-agent-policy-enforcement

Repository files navigation

AI Agent Policy Enforcement

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


The Problem

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_table was 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.


The Solution: Gateway-Enforced Action Policies

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

Quick Start

Set an action policy (allowlist)

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.*"]}

What happens when a blocked intent is sent

# 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.

Set a denylist (block specific actions)

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.


Using the CLI

# 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 receive

Dashboard

Agent Mesh Dashboard

View and manage action policies visually at mesh.axme.ai under the Policies tab.

Agent Mesh Policies

  • Select an agent from the mesh
  • Set allowlist/denylist per direction
  • See violations in the audit log
  • Monitor which intents are being blocked

Full Working Example

1. Define the scenario

{
  "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
  }
}

2. Apply the scenario and set the policy

# 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.*"

3. Run the agent

AXME_API_KEY=<agent-key> python agent.py

4. Try sending a blocked intent

# 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

Why Gateway Enforcement Matters

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

Pattern Matching

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

Works With Any Agent Framework

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

Related


License

MIT


Built with AXME (AXP Intent Protocol).

About

Gateway-enforced action policies for AI agents. Allowlist/denylist what your agents can do - enforced at the network level, not inside the prompt.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages