> ## Documentation Index
> Fetch the complete documentation index at: https://agentcontrol-simplify-quickstarts.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Controls

> Understand how controls work and how to define them.

<img src="https://mintcdn.com/agentcontrol-simplify-quickstarts/uVCvVTHKF-PqEA3i/concepts/Controls.png?fit=max&auto=format&n=uVCvVTHKF-PqEA3i&q=85&s=e5714db60273a71c845dd7742f27c980" alt="Control Components" width="1460" height="774" data-path="concepts/Controls.png" />

A Control is a protection rule that evaluates agent interactions (inputs/outputs) and takes action based on configured criteria. It defines when to check, what to check, how to evaluate it, and what to do with the results.

Control formula: **Control = Scope (When) + Selector (What) + Evaluator (How) + Action (Decision)**

## 1. Scope (When to Check)

The **Scope** defines which steps trigger the control—acting as a filter to select specific sections of your agent workflow to monitor.

Fields:

* `step_types`: List of step types (`['tool', 'llm']`). If null, applies to all types.

* `step_names`: List of exact step names to target (e.g., `['search_db', 'send_email']`)

* `step_name_regex`: Regex pattern for step name matching (e.g., `"^db.*"` matches all "db\_" prefixed steps)

* `stages`: When to evaluate - `['pre', 'post']`

  * `'pre'`: Check before execution (block bad inputs, prevent prompt injection)

  * `'post'`: Check after execution (filter bad outputs, redact PII)

### Example 1: Apply to all tool steps before execution

```json theme={null}
{
  "scope": {
    "step_types": ["tool"],
    "stages": ["pre"]
  }
}
```

### Example 2: Target specific database operations

```json theme={null}
{
  "scope": {
    "step_names": ["query_database", "execute_sql", "db_lookup"],
    "stages": ["pre"]
  }
}
```

### Example 3: Use regex to match multiple steps

```json theme={null}
{
  "scope": {
    "step_name_regex": "^db_.*",  // Matches all steps starting with "db_"
    "stages": ["pre", "post"]
  }
}
```

### Example 4: Full scope configuration

```json theme={null}
{
  "scope": {
    "step_types": ["tool", "llm"],
    "step_names": ["search_db", "query_api"],
    "step_name_regex": "^db_.*",
    "stages": ["pre", "post"]
  }
}
```

***

## 2. Selector (What to Check)

The **Selector** specifies which portion of the step's data to extract and pass to the evaluator for analysis. It uses a path specification to navigate the step object.

Field:

* `path`: Dot-notation path to the data you want to evaluate

Common Paths:

* `"input"` - Entire input to the step

* `"output"` - Step's output/result

* `"input.query"` - Specific parameter within input

* `"input.user_message"` - User message field

* `"name"` - The step/tool name itself

* `"context.user_id"` - Context metadata

* `"*"` - All available payload data

### Example 1: Check tool output for PII

```json theme={null}
{
  "selector": {
    "path": "output"
  }
}
```

### Example 2: Validate specific input parameter

```json theme={null}
{
  "selector": {
    "path": "input.sql_query"
  }
}
```

### Example 3: Check user message in LLM input

```json theme={null}
{
  "selector": {
    "path": "input.user_message"
  }
}
```

### Example 4: Access context metadata

```json theme={null}
{
  "selector": {
    "path": "context.user_id"
  }
}
```

***

## 3. Evaluator (How to Check)

The **Evaluator** receives the data extracted by the selector and evaluates it against configured rules, returning whether the data matches specified criteria.

Components:

* `config`: Evaluator-specific configuration, validated against the evaluator's schema

* `metadata`: Optional evaluator identification

### Example 1: Regex evaluator to detect PII

```json theme={null}
{
  "evaluator": {
    "name": "regex",
    "config": {
      "pattern": "\\b\\d{3}-\\d{2}-\\d{4}\\b"  // Social Security Number pattern
    }
  }
}
```

### Example 2: List evaluator for banned terms

```json theme={null}
{
  "evaluator": {
    "name": "list",
    "config": {
      "values": ["DROP TABLE", "DELETE FROM", "TRUNCATE"],
      "case_sensitive": false
    }
  }
}
```

### Example 3: AI-powered toxicity detection with Luna-2

To use this evaluator, install the package:

```bash theme={null}
pip install agent-control-evaluators[galileo]
```

```json theme={null}
{
  "evaluator": {
    "name": "galileo.luna2",
    "config": {
      "metric": "input_toxicity",
      "operator": "gt",
      "target_value": 0.5
    }
  }
}
```

### Example 4: Complex regex for multiple PII types

```json theme={null}
{
  "evaluator": {
    "name": "regex",
    "config": {
      "pattern": "(?:\\b\\d{3}-\\d{2}-\\d{4}\\b|\\b\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}\\b|[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})"
    }
  }
}
```

Custom Evaluators:
Agent Control supports custom evaluators for domain-specific requirements. See [examples/DeepEval](/examples/deepeval) for a complete example of creating and integrating custom evaluators.

***

## 4. Action (What to Do)

The **Action** defines what happens when the evaluator matches/detects an issue.

Fields:

* `decision`: The enforcement action to take

  * `"allow"` - Continue execution (useful for allowlist controls)

  * `"deny"` - Hard stop execution (blocks the request)

  * `"steer"` - Provides corrective guidance to help agents satisfy control requirement

  * `"warn"` - Log a warning but continue execution

  * `"log"` - Log the match for observability only

* `metadata`: Optional additional context (JSON object)

### Important: "Deny Wins" Semantics

Agent Control uses "deny wins" logic: if **any** enabled control with a `deny` action matches, the request is blocked regardless of other control results. This ensures fail-safe behavior.

### Example 1: Block on match

```json theme={null}
{
  "action": {
    "decision": "deny"
  }
}
```

### Example 2: Warn without blocking

```json theme={null}
{
  "action": {
    "decision": "warn"
  }
}
```

### Example 3: Action with metadata

```json theme={null}
{
  "action": {
    "decision": "deny",
    "metadata": {
      "reason": "PII detected in output",
      "severity": "high",
      "compliance": "GDPR"
    }
  }
}
```

### Example 4: Action with steer and steering context

```json theme={null}
{
  "action": {
    "decision": "steer",
    "steering_context": {
      "message": "Remove PII and rephrase the response without account numbers or SSNs.",
      "required_actions": [
        "redact_pii",
        "generalize_account_details"
      ]
    },
    "metadata": {
      "reason": "PII detected in output",
      "severity": "medium",
      "compliance": "GDPR"
    }
  }
}
```

***

## Complete Control Example

Putting it all together - a control that blocks Social Security Numbers in tool outputs:

```json theme={null}
{
  "name": "block-ssn-output",
  "description": "Prevent SSN leakage in tool responses",
  "enabled": true,
  "scope": {
    "step_types": ["tool"],
    "stages": ["post"]
  },
  "selector": {
    "path": "output"
  },
  "evaluator": {
    "name": "regex",
    "config": {
      "pattern": "\\b\\d{3}-\\d{2}-\\d{4}\\b"
    }
  },
  "action": {
    "decision": "deny",
    "metadata": {
      "reason": "SSN detected",
      "compliance": "PII protection"
    }
  }
}
```

***

## Defining Controls

You can create and configure controls via the SDK, API, or UI.

### Example: Block PII in Output (Regex)

Via Python SDK:

```python theme={null}
from agent_control import AgentControlClient, controls

async with AgentControlClient() as client:
    await controls.create_control(
        client,
        name="block-ssn-output",
        data={
            "description": "Block Social Security Numbers in responses",
            "enabled": True,
            "execution": "server",
            "scope": {"step_names": ["generate_response"], "stages": ["post"]},
            "selector": {"path": "output"},
            "evaluator": {
                "name": "regex",
                "config": {"pattern": r"\\b\\d{3}-\\d{2}-\\d{4}\\b"}
            },
            "action": {"decision": "deny"}
        }
    )
```

Via curl:

```bash theme={null}

# Step 1: Create control

CONTROL_ID=$(curl -X PUT http://localhost:8000/api/v1/controls \
  -H "Content-Type: application/json" \
  -d '{"name": "block-ssn-output"}' | jq -r '.control_id')

# Step 2: Set control configuration

curl -X PUT "http://localhost:8000/api/v1/controls/$CONTROL_ID/data" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "description": "Block Social Security Numbers in responses",
      "enabled": true,
      "execution": "server",
      "scope": {"step_names": ["generate_response"], "stages": ["post"]},
      "selector": {"path": "output"},
      "evaluator": {
        "name": "regex",
        "config": {"pattern": "\\\\b\\\\d{3}-\\\\d{2}-\\\\d{4}\\\\b"}
      },
      "action": {"decision": "deny"}
    }
  }'
```

### Example: Block Toxic Input (Luna-2 AI)

To use this evaluator, install the package and restart the server.

```bash theme={null}
pip install agent-control-evaluators[galileo]
```

Via Python SDK:

```python theme={null}
await controls.create_control(
    client,
    name="block-toxic-input",
    data={
        "description": "Block toxic or harmful user messages",
        "enabled": True,
        "execution": "server",
        "scope": {"step_names": ["process_user_message"], "step_types": ["llm"], "stages": ["pre"]},
        "selector": {"path": "input"},
        "evaluator": {
            "name": "galileo.luna2",
            "config": {
                "metric": "input_toxicity",
                "operator": "gt",
                "target_value": 0.5
            }
        },
        "action": {"decision": "deny"}
    }
)
```

Via curl:

```bash theme={null}

# Create control with Luna-2 evaluator

CONTROL_ID=$(curl -X PUT http://localhost:8000/api/v1/controls \
  -H "Content-Type: application/json" \
  -d '{"name": "block-toxic-input"}' | jq -r '.control_id')

curl -X PUT "http://localhost:8000/api/v1/controls/$CONTROL_ID/data" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "description": "Block toxic or harmful user messages",
      "enabled": true,
      "execution": "server",
      "scope": {"step_names": ["process_user_message"], "step_types": ["llm"], "stages": ["pre"]},
      "selector": {"path": "input"},
      "evaluator": {
        "name": "galileo.luna2",
        "config": {
          "metric": "input_toxicity",
          "operator": "gt",
          "target_value": 0.5
        }
      },
      "action": {"decision": "deny"}
    }
  }'
```

> **Note**: For the Luna-2 evaluator, set the `GALILEO_API_KEY` environment variable. See the [Evaluators](/concepts/evaluators/overview) for all available evaluators.
