AskTable
sidebar.freeTrial

AskTable Agent Sandbox: Running AI-Generated Python, SQL, and JSX Safely

AskTable Team
AskTable Team 2026-03-05

In AI Canvas, users can have AI generate and execute Python code, SQL queries, and JSX charts. How do we ensure the secure execution of this code? How do we prevent malicious code from damaging the system? How do we limit resource consumption?

AskTable's Agent sandbox execution environment implements secure and reliable code execution through resource limits + timeout management + permission control multi-layer protection.


1. Why Do We Need Sandboxes?

1.1 Risks of AI-Generated Code

Malicious Code:

# Dangerous code AI might generate
import os
os.system("rm -rf /")  # Delete system files

Resource Exhaustion:

# Infinite loop
while True:
    pass

# Memory exhaustion
data = [0] * (10 ** 10)

Data Leakage:

# Read sensitive files
with open("/etc/passwd") as f:
    print(f.read())

1.2 Core Goals of Sandboxes

Isolation: Code execution doesn't affect the host system ✅ Resource Limits: Limit CPU, memory, execution time ✅ Permission Control: Prohibit access to sensitive resources ✅ Error Isolation: Exceptions don't affect other tasks


2. Python Sandbox Implementation

2.1 RestrictedPython Limitations

from RestrictedPython import compile_restricted, safe_globals

def execute_python_code(code: str, context: dict) -> Any:
    """Execute Python code in restricted environment"""
    # 1. Compile restricted code
    byte_code = compile_restricted(
        code,
        filename="<user_code>",
        mode="exec"
    )

    # 2. Prepare safe globals
    restricted_globals = {
        **safe_globals,
        "__builtins__": {
            "print": print,
            "len": len,
            "range": range,
            "sum": sum,
            # Only expose safe builtins
        },
        "pd": pd,  # pandas
        "np": np,  # numpy
    }

    # 3. Execute code
    exec(byte_code, restricted_globals, context)

    return context.get("result")

Restricted Content:

  • ❌ Forbidden import os, import sys
  • ❌ Forbidden open(), eval(), exec()
  • ❌ Forbidden access to __import__
  • ✅ Only allow safe libraries (pandas, numpy)

2.2 Timeout Management

import signal
from contextlib import contextmanager

@contextmanager
def timeout(seconds: int):
    """Timeout context manager"""
    def timeout_handler(signum, frame):
        raise TimeoutError(f"Execution timeout after {seconds}s")

    # Set timeout signal
    signal.signal(signal.SIGALRM, timeout_handler)
    signal.alarm(seconds)

    try:
        yield
    finally:
        signal.alarm(0)  # Cancel timeout

# Usage
with timeout(30):
    execute_python_code(code, context)

2.3 Resource Limits

import resource

def set_resource_limits():
    """Set resource limits"""
    # Limit memory (512MB)
    resource.setrlimit(
        resource.RLIMIT_AS,
        (512 * 1024 * 1024, 512 * 1024 * 1024)
    )

    # Limit CPU time (30 seconds)
    resource.setrlimit(
        resource.RLIMIT_CPU,
        (30, 30)
    )

    # Limit file size (10MB)
    resource.setrlimit(
        resource.RLIMIT_FSIZE,
        (10 * 1024 * 1024, 10 * 1024 * 1024)
    )

3. SQL Sandbox Implementation

3.1 Read-Only Permissions

async def execute_sql_readonly(sql: str, datasource: DataSourceAdmin) -> pd.DataFrame:
    """Execute SQL read-only"""
    # 1. Check SQL type
    if not is_select_query(sql):
        raise errors.SecurityError("Only SELECT queries are allowed")

    # 2. Use read-only connection
    async with datasource.get_readonly_connection() as conn:
        df = await conn.execute(sql)

    return df

def is_select_query(sql: str) -> bool:
    """Check if it's a SELECT query"""
    parsed = sqlglot.parse_one(sql)
    return isinstance(parsed, exp.Select)

3.2 Timeout Control

async def execute_sql_with_timeout(
    sql: str, datasource: DataSourceAdmin, timeout_seconds: int = 30
) -> pd.DataFrame:
    """SQL execution with timeout"""
    try:
        df = await asyncio.wait_for(
            datasource.execute_sql(sql),
            timeout=timeout_seconds
        )
        return df
    except asyncio.TimeoutError:
        raise errors.QueryTimeout(f"Query timeout after {timeout_seconds}s")

3.3 Row Limit

async def execute_sql_with_limit(
    sql: str, datasource: DataSourceAdmin, max_rows: int = 10000
) -> pd.DataFrame:
    """Limit returned rows"""
    # 1. Parse SQL
    parsed = sqlglot.parse_one(sql, read=datasource.dialect)

    # 2. Add LIMIT clause
    if not parsed.find(exp.Limit):
        parsed = parsed.limit(max_rows)

    # 3. Execute
    modified_sql = parsed.sql(dialect=datasource.dialect)
    df = await datasource.execute_sql(modified_sql)

    return df

4. JSX Sandbox Implementation

4.1 JSX Compilation

import subprocess

def compile_jsx(jsx_code: str) -> str:
    """Compile JSX to JavaScript"""
    # Use esbuild for compilation
    result = subprocess.run(
        ["esbuild", "--loader=jsx", "--format=iife"],
        input=jsx_code.encode(),
        capture_output=True,
        timeout=5,
    )

    if result.returncode != 0:
        raise errors.CompilationError(result.stderr.decode())

    return result.stdout.decode()

4.2 Browser Sandbox

// Frontend executes JSX (isolated in iframe)
function executeJSX(compiledCode) {
    const iframe = document.createElement('iframe');
    iframe.sandbox = 'allow-scripts';  // Only allow script execution
    iframe.style.display = 'none';
    document.body.appendChild(iframe);

    const iframeDoc = iframe.contentDocument;
    const script = iframeDoc.createElement('script');
    script.textContent = compiledCode;
    iframeDoc.body.appendChild(script);
}

5. Practical Cases

Case 1: Python Data Processing

# User code
code = """
import pandas as pd

# Load parent node data
df = parent_dataframes[0]

# Data cleaning
df_clean = df.dropna()
df_clean['amount'] = df_clean['amount'].astype(float)

# Calculate statistics
result = df_clean.groupby('category')['amount'].sum()
"""

# Secure execution
context = {"parent_dataframes": [df1, df2]}
with timeout(30):
    set_resource_limits()
    result = execute_python_code(code, context)

Case 2: SQL Query

# User SQL
sql = "SELECT * FROM orders WHERE amount > 1000"

# Secure execution
df = await execute_sql_with_timeout(
    sql,
    datasource,
    timeout_seconds=30
)

6. Summary

AskTable's sandbox execution environment implements secure and reliable code execution through multi-layer protection:

Python: RestrictedPython + timeout + resource limits ✅ SQL: Read-only permissions + timeout + row limits ✅ JSX: Compilation isolation + browser sandbox


Related Reading:

Technical Exchange:

cta.readyToSimplify

sidebar.noProgrammingNeededsidebar.startFreeTrial

cta.noCreditCard
cta.quickStart
cta.dbSupport