AID-H-025.002: Safe Interpreter Enforcement
Pillars: app
Lifecycle: building, operation
Scope boundary
Owns mandatory selection and configuration of a restricted interpreter when dynamic evaluation is allowed. It limits the language and API surface but is not the process, filesystem, network, or resource containment boundary.
AID-H-025.001: AID-H-025.002 constrains code that is allowed to run; AID-H-025.001 decides whether exact code bytes contain policy-prohibited constructs before execution. Interpreter restriction and static admission address different failure modes.
AID-I-001: AID-H-025.002 restricts language semantics inside an evaluator; AID-I-001 contains the evaluator process and its operating-system effects. A restricted interpreter escape must still meet a separate sandbox boundary.
AID-H-018.009: AID-H-025.002 selects and configures the restricted interpreter and authorizes code evaluation; AID-H-018.009 confines any model-influenced interpreter, script, module, working-directory, or executable filesystem target. Interpreter admission and opened-object confinement remain separate results, and execution permission stays with this control and AID-I-001.
Warning
Restricted Interpreter Is Not a Complete Sandbox
Restricted interpreters are security-sensitive dependencies. Use a supported release, track published escape fixes, and regression-test the exact language and built-in surface enabled by policy before promotion.
Implementation guidance
- AID-H-025.002-G001: Allowlist restricted interpreters and enforce interpreter selection via an execution gateway (policy), not via model output.
AID-H-025.002-G001
Action: enforce the restricted-interpreter boundary
- Restricted interpreters only: allowlist approved evaluators (literal-only, restricted subsets) and pin RestrictedPython to 8.3 or newer.
- Ephemeral sandboxes: for vibe coding, run code in short-lived containers/WASM runtimes and delete the environment after execution.
- Deny-by-default: no outbound network, non-root, confined working directory.
Example code (Python) - restricted interpreter inside a sandbox
from importlib.metadata import version
import os
from pathlib import Path
from packaging.version import Version
from RestrictedPython import compile_restricted
from RestrictedPython import safe_globals
if Version(version("RestrictedPython")) < Version("8.3"):
raise RuntimeError("RestrictedPython 8.3+ is required; older releases are not accepted")
# This function must be invoked only inside a short-lived OS/container/WASM sandbox
# with no outbound network, non-root execution, and a minimal writable filesystem.
def run_restricted(code_str: str) -> None:
if not isinstance(code_str, str) or not code_str:
raise ValueError("restricted source must be non-empty text")
byte_code = compile_restricted(code_str, "<agent-code>", "exec")
globals_map = dict(safe_globals)
exec(byte_code, globals_map, {})
if __name__ == "__main__":
# The immutable workload artifact exposes exactly this gateway-selected path.
source_path = Path("/workspace/untrusted.py")
requested = Path(os.path.abspath(os.sys.argv[1])) if len(os.sys.argv) == 2 else None
if requested != source_path or source_path.is_symlink() or not source_path.is_file():
raise SystemExit("usage: run_restricted.py /workspace/untrusted.py")
maximum = int(os.environ["SANDBOX_SOURCE_MAX_BYTES"])
if maximum < 1 or maximum > 1_048_576:
raise RuntimeError("sandbox source cap is invalid")
raw = source_path.read_bytes()
if not raw or len(raw) > maximum:
raise RuntimeError("restricted source violates the byte cap")
run_restricted(raw.decode("utf-8", errors="strict"))Boundary: RestrictedPython is a language-surface reduction layer, not an operating-system sandbox. The execution gateway must select the approved interpreter and sandbox image; model output must never choose either one.
Enforce the outer boundary
: "${BROKERED_WORKLOAD_IMAGE:?gateway must supply an H-018.009-bound workload image}"
: "${BROKERED_WORKLOAD_RECEIPT_ID:?gateway must supply the opened-artifact receipt ID}"
case "$BROKERED_WORKLOAD_IMAGE" in
*@sha256:*) ;;
*) echo "BROKERED_WORKLOAD_IMAGE must be pinned by digest" >&2; exit 2 ;;
esac
: "${SANDBOX_PIDS_LIMIT:?load SANDBOX_PIDS_LIMIT from the verified sandbox policy}"
: "${SANDBOX_MEMORY_LIMIT:?load SANDBOX_MEMORY_LIMIT from the verified sandbox policy}"
: "${SANDBOX_CPU_LIMIT:?load SANDBOX_CPU_LIMIT from the verified sandbox policy}"
: "${SANDBOX_USER:?load SANDBOX_USER from the verified sandbox policy}"
: "${SANDBOX_TMPFS_SIZE:?load SANDBOX_TMPFS_SIZE from the verified sandbox policy}"
: "${SANDBOX_SOURCE_MAX_BYTES:?load SANDBOX_SOURCE_MAX_BYTES from the verified sandbox policy}"
docker run --rm \
--network=none \
--read-only \
--cap-drop=ALL \
--security-opt=no-new-privileges \
--pids-limit="$SANDBOX_PIDS_LIMIT" \
--memory="$SANDBOX_MEMORY_LIMIT" \
--cpus="$SANDBOX_CPU_LIMIT" \
--user="$SANDBOX_USER" \
--tmpfs "/tmp:rw,noexec,nosuid,nodev,size=$SANDBOX_TMPFS_SIZE" \
--env "SANDBOX_SOURCE_MAX_BYTES=$SANDBOX_SOURCE_MAX_BYTES" \
--workdir /workspace \
"$BROKERED_WORKLOAD_IMAGE" \
/opt/aidefend/venv/bin/python \
/opt/aidefend/run_restricted.py \
/workspace/untrusted.pyThe code-execution gateway, not model text or an ambient $PWD/PATH, selects the exact interpreter, runner, and workspace artifact. Before this sandbox step it consumes AID-H-018.009 broker-opened handles or a content-addressed workload artifact and binds that receipt to BROKERED_WORKLOAD_IMAGE; the reference command never reopens a model-supplied host path and does not claim filesystem-confinement PASS. The runtime-platform team applies this guidance to every model- or user-supplied execution request. A separately credentialed verifier reconciles the complete request population against gateway decisions, broker receipt IDs, immutable runtime/workload image identities, resource and syscall traces, and the external network-canary readback; the executor's own verdict is never sufficient.
Negative tests and evidence
Exercise imports, file reads/writes, subprocess creation, sockets, excessive CPU, memory exhaustion, fork attempts, ambient $PWD/PATH substitution, wrong artifact or receipt reuse, and writes outside the temporary directory. Run a separate network canary outside the container and prove that no connection arrives. Require the expected language-level denials plus container/runtime enforcement; a crash, timeout, missing telemetry, mutable image reference, or unsupported runtime must block release. Preserve the interpreter and package versions, immutable workload image digest, broker receipt ID, gateway decision, runtime policy, exit reason, resource telemetry, syscall/network evidence, and test-corpus digest.
Block release when any expected execution request, immutable workload image digest, broker receipt, runtime receipt, resource trace, network canary result, or negative-test case is absent. Exclude this method only when signed inventory proves that the covered workflow never evaluates or executes model- or user-supplied code; disabling one interpreter is insufficient.
Open-source tools
- RestrictedPython 8.3+ (Python)
- Docker Engine (orchestration only; pair with an independent sandbox boundary)
- Podman (orchestration only; pair with an independent sandbox boundary)
- gVisor
- Firecracker
- Wasmtime (WASM runtime)
- Wasmer (WASM runtime)
- nsjail (process and seccomp sandbox for untrusted code)
- Pyodide (WASM Python runtime; independently restrict host capabilities)
Commercial / hosted tools
- Azure Container Apps Dynamic Sessions (code-interpreter or custom-container sessions)
- E2B Sandboxes
- Modal Sandboxes
- Daytona Sandboxes
Threat mappings
MITRE ATLAS
- AML.T0050 Command and Scripting Interpreter
- AML.T0072 Cyber Communication Channel (restricted interpreters deny network access, so evaluated code cannot establish callback channels)
- AML.T0105 Escape to Host (restricted interpreters prevent filesystem/network access needed for host escape)
MAESTRO
- Agent Tool Misuse (L7)
OWASP LLM Top 10 2026
- LLM03:2026 Excessive Agency
- LLM10:2026 Improper Output Handling
OWASP ML Top 10 2023
- N/A
OWASP Top 10 for Agentic Applications 2026
- ASI05:2026 Unexpected Code Execution (RCE)
- ASI02:2026 Tool Misuse and Exploitation (restricted interpreters constrain what agent-generated code can do)
NIST Adversarial Machine Learning 2025
- NISTAML.039 Compromising connected resources (restricted interpreters prevent access to connected systems)
Cisco Integrated AI Security and Safety Framework
- AISubtech-12.1.3 Unsafe System / Browser / File Execution
- AISubtech-12.2.1 Code Detection / Malicious Code Output
- AISubtech-9.1.1 Code Execution
- AISubtech-9.1.2 Unauthorized or Unsolicited System Access
- AISubtech-9.1.3 Unauthorized or Unsolicited Network Access
- AITech-12.1 Tool Exploitation
- AITech-12.2 Insecure Output Handling
- AITech-9.1 Model or Agentic System Manipulation
Google Secure AI Framework 2.0 - Risks
- IMO: Insecure Model Output (restricted interpreters prevent unsafe code execution from model output)
- RA: Rogue Actions (restricted interpreters constrain agent code execution capabilities)
Databricks AI Security Framework 3.0
- Agents - Core 13.11: Unexpected RCE and Code Attacks
- Model Serving - Inference requests 9.3: Model breakout
- Agents - Tools MCP Client 13.32: Client-Side Code Execution