> ## Documentation Index
> Fetch the complete documentation index at: https://agentcontrol-abhi-agent-control-auth-contract-docs.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-abhi-agent-control-auth-contract-docs/dkRtv_kxIeJOTeuq/concepts/Controls.png?fit=max&auto=format&n=dkRtv_kxIeJOTeuq&q=85&s=549404b9d35020fef1d15d280db4088a" 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) + Condition (What + 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. Condition (What and How to Check)

The **Condition** is a recursive boolean tree. Leaf conditions pair a `selector` with an `evaluator`, and composite conditions can combine child conditions with `and`, `or`, and `not`.

### Example 1: Leaf condition that checks tool output for PII

```json theme={null}
{
  "condition": {
    "selector": {
      "path": "output"
    },
    "evaluator": {
      "name": "regex",
      "config": {
        "pattern": "\\b\\d{3}-\\d{2}-\\d{4}\\b"
      }
    }
  }
}
```

### Example 2: Composite condition with `and` and `not`

```json theme={null}
{
  "condition": {
    "and": [
      {
        "selector": {
          "path": "context.risk_level"
        },
        "evaluator": {
          "name": "list",
          "config": {
            "values": ["high", "critical"]
          }
        }
      },
      {
        "not": {
          "selector": {
            "path": "context.user_role"
          },
          "evaluator": {
            "name": "list",
            "config": {
              "values": ["admin", "security"]
            }
          }
        }
      }
    ]
  }
}
```

### 2.1 Selector (What to Check Inside a Leaf)

Inside a leaf condition, 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"
  }
}
```

***

### 2.2 Evaluator (How to Check Inside a Leaf)

Inside a leaf condition, 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.

***

## 3. Action (What to Do)

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

Fields:

* `decision`: The enforcement action to take

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

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

  * `"observe"` - Record the match for audit and observability without blocking execution

* `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: Observe without blocking

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

### 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"]
  },
  "condition": {
    "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"]},
            "condition": {
                "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}

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

Regex pattern note: the pattern itself is `\b\d{3}-\d{2}-\d{4}\b`. Python raw strings render that as `r"\b\d{3}-\d{2}-\d{4}\b"`, while JSON payloads must escape backslashes as `"\\b\\d{3}-\\d{2}-\\d{4}\\b"`.

### 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"]},
        "condition": {
            "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}

CONTROL_ID=$(curl -X PUT http://localhost:8000/api/v1/controls \
  -H "Content-Type: application/json" \
  -d '{
    "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"]},
      "condition": {
        "selector": {"path": "input"},
        "evaluator": {
          "name": "galileo.luna2",
          "config": {
            "metric": "input_toxicity",
            "operator": "gt",
            "target_value": 0.5
          }
        }
      },
      "action": {"decision": "deny"}
    }
  }' | jq -r '.control_id')
```

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