Skip to content

Interpreter ring — code execution rules

What it does: Limits which imports, binaries, and network the agent's code can use when it runs (Python, shell, etc.).

Some agents run code as part of their work — a data engineer agent runs SQL, a code reviewer agent runs gh, a Python REPL agent evaluates arbitrary code. Without code-execution governance, the agent can use legitimate facilities to do illegitimate things: import a Collibra REST client, paste a credential into a request body, exfiltrate via DNS.

This layer constrains the executor: what imports are allowed, what binaries are reachable, what network the executor can use. For agents that don't run code (LangChain ReAct with only function tools), this layer is a no-op — but it's pre-wired so adding code-mode later doesn't require a new layer.

See governed-agents.md §9 and the bypass matrix — this ring is where "agent code tries requests.delete(…)" gets caught alongside the Kernel ring.

Inputs: the interpreter aspect of the Compiled Policy plus a runtime profile derived from network and filesystem:

interpreter_ring:
allowed_imports:
- "pandas"
- "numpy"
- "tappass_agent"
denied_imports:
- "requests" # force HTTP through tappass-agent's gateway client
- "urllib3"
- "collibra_client" # internal-only Python library; agent shouldn't reach Collibra directly
executor_network: tappass-only # or "off", "kernel-allowlist"
allowed_binaries:
- "/usr/bin/git"
denied_patterns:
- "rm -rf"
- "curl"

Outputs: a configured executor (Python sandbox profile, shell wrapper, etc.) that enforces the rules at execution time.

Error cases:

  • Profile rejected by executor → fail sandbox apply (fail-closed).
  • Executor doesn't support hot-reload → flag for restart on next sync push.

Where it lives: tappass-host/src/layers/codemode.py. Wraps Monty (or equivalent code-mode sandbox) profiles.

Approach: the codemode layer doesn't need to invent enforcement — it composes existing primitives:

  • For Python: a sys.modules allowlist + import hook installed in the executor at startup. Denied imports raise ImportError.
  • For shell: PATH restricted to allowed_binaries; pattern match on commands rejects denied patterns before invocation.
  • For network from the executor: routes through inference.local (which respects the kernel egress allowlist).
  • All acceptance_criteria pass.
  • Python executor profile applied; denied imports raise ImportError at the agent.
  • Shell executor profile applied; denied patterns refused before invocation.
  • Sync-push reload tested.
  • No-op path tested for runtimes that don't expose codemode.

With ring-kernel: redundant defense — even if a denied import slips through, the kernel egress allowlist denies the resulting network call.

Open questions:

  • (Q) Which executor primitives do we reuse vs. build new? Lean: reuse Monty if its profile shape matches; otherwise wrap with a thin layer. Owner: this component.
  • Authoring the rules — that's the policy and the policy-to-sandbox-config-builder.
  • Defending against compiled binaries the agent invokes via Bash — those go through the harness allow/deny (Layer 2) and the kernel egress (Layer 1).