CODE EXECUTOR · IMPORT POLICY
ADK code executor: reject a forbidden import
Scan an editable script for static and computed imports, apply an allowlist or denylist, and see whether a file-system effect could run.
Event trace
Computed data
Final metrics
Teaching scanner, not a Python sandbox or the ADK BuiltInCodeExecutor. It recognizes import, from-import, __import__, importlib.import_module, exec and eval by pattern; effects are inferred from text such as open( or read_text(, and nothing is executed. A real executor must also isolate the process, file system and network, because import checks alone can be bypassed.
Scan before anything runs
The script in the editor is scanned line by line before any statement could execute. The scanner recognizes import and from-import statements, __import__ and importlib.import_module calls, and exec or eval. Each import becomes a row in the computed table with its line, module and the policy decision. Nothing is executed: the possible effects shown at the end are inferred from the text, such as an open( or read_text( call. The opening example imports math and os and then reads /etc/hostname.
Allowlist versus denylist
With Import policy set to allowlist and the allowlist math, statistics, json, line 1 is allowed and line 2 is rejected because os is not listed. Execution is refused before the first statement, so the outcome is safe. Switch the policy to denylist: os is on the denylist, so the result is the same. Now load the pathlib example. The allowlist still rejects it, but the denylist lets pathlib through and the script reads /etc/passwd: unsafe, with a file-read effect. A denylist has to anticipate every dangerous module; an allowlist only has to name the safe ones.
Computed module names
Load the computed __import__ example. The module name is built from "o" + "s", so no static scan can know it. With Reject imports whose module name is computed at run time enabled, line 3 is rejected under either list policy. Clear that option and the scanner skips the computed import: math is allowed, nothing is rejected, and the script inspects the working directory. The aliased example, from os import path as p, is caught under both lists because the scanner reads the module before the alias.
Edit the policy yourself
The Script editor, Allowlisted modules and Denylisted modules fields are live inputs. Add os to the allowlist and the file-read example becomes unsafe. Choose No import policy and every script runs; only the arithmetic example stays safe, and it prints 6, the square root of three times the sum 12. Load an example script replaces the editor text and recomputes. Play, Pause, Next event, Restart, Speed and Inspection time step through the scan events over sixty seconds.
What a real executor needs
This is a pattern scanner, not a Python parser or the ADK built-in code executor. Import filtering is one layer only: attribute access, pickled objects, native extensions and many indirect routes can reach the same capabilities. Production executors run code in a separate process or container with no host file system, no network unless granted, CPU and memory limits, and a time limit. Treat a failed scan as an early, explainable rejection, not as the sandbox.