Skip to main content

Managing Execution Policies

Execution policies are hardrails that limit what data and tools an agent session can access, enforced by the platform rather than by the LLM. You can store policies as named, reusable objects and then apply them when creating sessions, defining agents, or running batch jobs. This guide covers the full lifecycle: creating policies, managing them, and applying them to agent executions.

Create an execution policy

Create a stored execution policy by providing a name and the policy payload. The policy defines datasource constraints, tool constraints, or both.
import os
from meibel import MeibelClient
from meibel.models import CreateExecutionPolicyRequest

client = MeibelClient(api_key=os.environ["MEIBEL_API_KEY"])

policy = client.execution_policies.create_execution_policy(body=CreateExecutionPolicyRequest(
    name="EU Region Policy",
    description="Restricts data access to EU region and hides sensitive columns",
    execution_policy={
        "datasources": {
            "ds_abc123": {
                "tables": {
                    "filter": {
                        "table.__name__": {"$in": ["orders", "customers"]},
                        "orders.region": "EU",
                    },
                    "hidden_columns": {
                        "customers": ["ssn", "credit_card"],
                    },
                },
            },
        },
        "tools": {
            "web_search": {"disabled": True},
        },
    },
))

print(policy.id, policy.name)
import { MeibelClient } from 'meibel';

const client = new MeibelClient({ apiKey: process.env.MEIBEL_API_KEY });

const policy = await client.executionPolicies.createExecutionPolicy({
  name: 'EU Region Policy',
  description: 'Restricts data access to EU region and hides sensitive columns',
  executionPolicy: {
    datasources: {
      ds_abc123: {
        tables: {
          filter: {
            'table.__name__': { $in: ['orders', 'customers'] },
            'orders.region': 'EU',
          },
          hidden_columns: {
            customers: ['ssn', 'credit_card'],
          },
        },
      },
    },
    tools: {
      web_search: { disabled: true },
    },
  },
});

console.log(policy.id, policy.name);
The response includes the policy’s id, name, description, execution_policy, and timestamps. Use the id for all subsequent operations.
Policy names must be unique within your project. Creating a policy with a name that already exists returns an error.

List execution policies

Retrieve all execution policies in your project.
policies = client.execution_policies.list_execution_policies()

for p in policies.data:
    print(f"{p.id}: {p.name}")
const policies = await client.executionPolicies.listExecutionPolicies();

for (const p of policies.data) {
  console.log(`${p.id}: ${p.name}`);
}

Get execution policy details

Retrieve a specific execution policy by ID.
policy = client.execution_policies.get_execution_policy(policy_id="pol_abc123")

print(policy.name)
print(policy.execution_policy)
const policy = await client.executionPolicies.getExecutionPolicy('pol_abc123');

console.log(policy.name);
console.log(policy.executionPolicy);

Update an execution policy

Modify a policy’s name, description, or constraints. Only the fields you include in the request body are changed.
from meibel.models import UpdateExecutionPolicyRequest

updated = client.execution_policies.update_execution_policy(
    policy_id="pol_abc123",
    body=UpdateExecutionPolicyRequest(
        description="Updated: EU region with tighter tool constraints",
        execution_policy={
            "datasources": {
                "ds_abc123": {
                    "tables": {
                        "filter": {
                            "table.__name__": {"$in": ["orders", "customers"]},
                            "orders.region": "EU",
                        },
                        "hidden_columns": {
                            "customers": ["ssn", "credit_card"],
                        },
                    },
                },
            },
            "tools": {
                "web_search": {"disabled": True},
                "send_email": {
                    "variables": {
                        "to": "support@acme.com",
                    },
                },
            },
        },
    ),
)

print(updated.name)
const updated = await client.executionPolicies.updateExecutionPolicy('pol_abc123', {
  description: 'Updated: EU region with tighter tool constraints',
  executionPolicy: {
    datasources: {
      ds_abc123: {
        tables: {
          filter: {
            'table.__name__': { $in: ['orders', 'customers'] },
            'orders.region': 'EU',
          },
          hidden_columns: {
            customers: ['ssn', 'credit_card'],
          },
        },
      },
    },
    tools: {
      web_search: { disabled: true },
      send_email: {
        variables: {
          to: 'support@acme.com',
        },
      },
    },
  },
});

console.log(updated.name);

Delete an execution policy

Remove an execution policy. The policy is soft-deleted and no longer appears in list results.
client.execution_policies.delete_execution_policy(policy_id="pol_abc123")
await client.executionPolicies.deleteExecutionPolicy('pol_abc123');
Deleting a policy does not retroactively affect sessions or executions that already used it. Those sessions retain the policy that was composed at creation time.

Apply policies to a session

Pass stored policy IDs, an inline policy, or both when creating a session. When both are provided, they are composed together.
from meibel.models import CreateSessionRequest

# Apply a stored policy by ID
session = client.agents.create_session(
    agent_id="agent_abc123",
    body=CreateSessionRequest(
        execution_policy_ids=["pol_abc123"],
    ),
)

print(session.session_id)
// Apply a stored policy by ID
const session = await client.agents.createSession('agent_abc123', {
  executionPolicyIds: ['pol_abc123'],
});

console.log(session.sessionId);
You can also pass an inline policy directly, which is useful for per-user constraints that do not need to be stored:
session = client.agents.create_session(
    agent_id="agent_abc123",
    body=CreateSessionRequest(
        execution_policy={
            "datasources": {
                "ds_abc123": {
                    "documents": {
                        "filter": {
                            "data_element.__id__": {"$in": ["de_001", "de_002"]},
                        },
                    },
                },
            },
        },
    ),
)
const session = await client.agents.createSession('agent_abc123', {
  executionPolicy: {
    datasources: {
      ds_abc123: {
        documents: {
          filter: {
            'data_element.__id__': { $in: ['de_001', 'de_002'] },
          },
        },
      },
    },
  },
});
When you pass both execution_policy_ids and execution_policy, the stored policies are resolved first, then the inline policy is composed on top. All filters are merged with $and semantics, so the effective policy is the intersection of all constraints.

Apply policies to an agent definition

Set default execution policies on an agent definition so they apply to every session created against that agent. These can be stored policy references, an inline policy, or both.
from meibel.models import CreateAgentDefinitionRequest

agent = client.agents.create_agent(body=CreateAgentDefinitionRequest(
    display_name="Support Agent",
    instructions="You are a support assistant. Answer questions using the knowledge base.",
    execution_policy_ids=["pol_abc123", "pol_def456"],
    execution_policy={
        "tools": {
            "delete_record": {"disabled": True},
        },
    },
))

print(agent.id)
const agent = await client.agents.createAgent({
  displayName: 'Support Agent',
  instructions: 'You are a support assistant. Answer questions using the knowledge base.',
  executionPolicyIds: ['pol_abc123', 'pol_def456'],
  executionPolicy: {
    tools: {
      delete_record: { disabled: true },
    },
  },
});

console.log(agent.id);
Definition-level policies compose with session-level policies when a session is created. The definition policies are applied first, then session-level policies are layered on top. Because composition only narrows access, session-level policies cannot grant access beyond what the agent definition allows.

Apply policies to a batch execution

Pass execution policies when executing a batch definition to scope the data each item in the batch can access.
from meibel.models import ExecuteBatchDefinitionRequest

execution = client.batches.execute_batch_definition(
    definition_id="bdef_abc123",
    body=ExecuteBatchDefinitionRequest(
        execution_policy_ids=["pol_abc123"],
        execution_policy={
            "datasources": {
                "ds_abc123": {
                    "tables": {
                        "filter": {
                            "orders.region": "EU",
                        },
                    },
                },
            },
        },
    ),
)

print(execution.execution_id)
const execution = await client.batches.executeBatchDefinition('bdef_abc123', {
  executionPolicyIds: ['pol_abc123'],
  executionPolicy: {
    datasources: {
      ds_abc123: {
        tables: {
          filter: {
            'orders.region': 'EU',
          },
        },
      },
    },
  },
});

console.log(execution.executionId);
As with agent sessions, batch-level policies compose with any policies set on the underlying batch definition.