Skip to main content
This example demonstrates integrating Agent Control with a LangChain SQL agent to block dangerous SQL operations.

Setup

1. Start the Agent Control Server (for remote execution)

IMPORTANT: You must start/restart the server to load the SQL evaluator!
Verify evaluators are loaded:

2. Set OpenAI API Key

3. Install pre-reqs

4. Setup SQL Controls (One-Time)

This creates:
  • SQL safety control (blocks DROP, DELETE, TRUNCATE, ALTER, GRANT)
  • Policy with the control
  • Assigns policy to the SQL agent
For local execution, create the control with execution: "sdk" in setup_sql_controls.py (see sql_control_data_sdk) and enable AGENT_CONTROL_LOCAL_EVAL=true when running the agent.

Running the Example

Local vs Remote Control Execution

Remote (server-side) controls:
  • Default mode
  • Requires running the Agent Control server
  • Uses @control() to call /api/v1/evaluation on the server
Local (SDK-side) controls:
  • Set AGENT_CONTROL_LOCAL_EVAL=true
  • Controls must be configured with execution: "sdk"
  • Uses agent_control.check_evaluation_with_local(...) before executing the tool
Example:

Expected Behavior

Safe Query (SELECT with LIMIT):
Dangerous Query (DROP TABLE):

How It Works

1. The @control() Decorator

2. Automatic Tool Call Detection

The @control() decorator:
  1. Detects this is a tool (via name attribute)
  2. Creates a Step payload with type="tool", name, and input
  3. Sends to server for evaluation before execution
  4. Blocks execution if control triggers deny action

3. SQL Control Execution

The SQL is evaluated using the sql evaluator:
  • Parses the query
  • Checks for blocked operations (DROP, DELETE, etc.)
  • Validates LIMIT clauses
  • Returns deny/observe decision

4. Fail-Safe Error Handling

If the control check fails with an error:
  • ✅ Execution is BLOCKED (fail-safe)
  • ✅ RuntimeError is raised
  • ❌ Query never executes

Troubleshooting

”Evaluator ‘sql’ not found”

Cause: Server was started before evaluators were installed, or using old code. Fix:

“Policy ‘sql-protection-policy’ already exists”

Cause: Setup script was run multiple times. Fix: Either delete the policy via the API or use a different name in setup_sql_controls.py.

DROP TABLE still executes

Causes:
  1. Server not running or evaluators not loaded (remote mode)
  2. Control not assigned to agent’s policy
  3. Control data missing/invalid (control not returned to agent)
  4. Local mode enabled but control is still execution: "server"
Fix:
  1. Restart server with make run
  2. Re-run setup_sql_controls.py
  3. Verify decorator code is up-to-date

Architecture

Files

  • sql_agent_protection.py - Main SQL agent with @control() decorator
  • setup_sql_controls.py - One-time setup script for controls/policy
  • pyproject.toml - Dependencies and configuration
  • README.md - This file

Key Security Features

  1. Fail-Safe by Default: Errors block execution
  2. Server-Side Validation: Remote controls enforced centrally
  3. SDK-Side Validation: Local controls run before tool execution
  4. Automatic Detection: Decorator auto-detects tool vs LLM calls

Source Code

View the complete example with all scripts and setup instructions: LangChain SQL Agent Example