# Secure Code Execution in AI Agents: Why Isolation Matters and How YepCode Helps

> LLM agents that execute code unlock power—and risk. This post explains why isolation is non‑negotiable and how to execute safely with YepCode Run plus file I/O via YepCode Storage.

## The problem: agents that run code… on your machine

Modern agent frameworks let LLMs generate and run code autonomously. That’s powerful—and risky. If code runs directly on the host, a single prompt‑injection or supply‑chain attack can exfiltrate data, delete files, mine crypto, or pivot across your network.

A recent survey of secure execution patterns in agents highlights the same conclusion many of us have reached: the only safe way to run LLM‑generated code is to isolate it from your local environment (via sandboxing/containers) and apply strict runtime controls.

## What “secure by design” looks like

When you let an LLM execute code, treat it as untrusted by default. A practical baseline includes:

* **Isolation**: per‑run sandbox or container, ephemeral filesystem, no host mounts
* **Resource limits**: CPU, memory, pids, timeouts, process count
* **Egress controls**: restrict outbound network or allowlist domains
* **Dependency hygiene**: deterministic installs, separate from host
* **Observability**: full logs, return values, and error traces for audit

> Market landscape: secure execution for agent code

Several companies are actively solving this secure‑execution pattern:

* **e2b**: provides hosted sandboxes that execute code out of process with real‑world tools and isolation. See their product overview at [e2b.dev](https://e2b.dev/).
* **Daytona**: focuses on standardized, ephemeral cloud development environments that can help teams isolate execution surfaces. Learn more at [daytona.io](https://www.daytona.io/).

Many of these approaches give agents a full ephemeral machine/“virtual computer.” That’s powerful, but it can add integration overhead and expand the governance surface.

YepCode takes a different path: a **developer‑first** execution plane. Instead of provisioning full machines, we provide purpose‑built, serverless sandboxes that are easy to integrate and operate while still covering real‑world needs (dependencies, secrets, scheduling, logs/results, audit).

## How YepCode fits: secure execution + simple I/O

**YepCode Run** gives you a serverless execution plane for JavaScript and Python that’s built on isolated sandboxes with automatic dependency installation, timeouts, logs, and return values. You send code; it runs safely; you get results. No Dockerfiles to maintain and no host exposure.

For handling inputs and outputs across runs or tools, **YepCode Storage** provides secure, API‑driven file storage. Use it to upload inputs (CSVs, PDFs, images), keep intermediate artifacts, and persist results. Each YepCode execution can receive [input parameters](/docs/processes/input-params/) and [return results](/docs/processes/source-code/#return-value) for structured data flow.

### Developer‑first by design

* **Dependencies out of the box**: import any npm/PyPI package; installs are handled for you per execution.
* **Team Variables & Secrets**: manage centrally; values are injected securely at runtime without exposing them to the LLM.
* **Scheduling**: trigger executions as cron jobs or on a schedule for recurring jobs and automations.
* **Results & logs**: stream logs, capture return values, and retrieve artifacts programmatically.
* **Enterprise‑grade audit**: who ran what and when, with execution metadata for compliance.

### Complete workflow: upload, process, and download

Here’s a complete example showing how to upload a file, process it securely with YepCode Run, and download the results:

* JavaScript

  ```js
  const { YepCodeRun, YepCodeStorage } = require("@yepcode/run");
  const fs = require("fs");


  const runner = new YepCodeRun({ apiToken: "<your-api-token-here>" });
  const storage = new YepCodeStorage({ apiToken: "<your-api-token-here>" });


  async function processData() {
    // 1. Upload input file
    await storage.upload("inputs/data.csv", fs.createReadStream("./data.csv"));


    // 2. Execute code that processes the file
    const execution = await runner.run(
      `async function main() {
        const fs = require("fs");
        const csv = require("csv-parser");


        // Download and process the CSV
        const stream = await yepcode.storage.download("inputs/data.csv");
        const results = [];


        return new Promise((resolve) => {
          stream.pipe(csv())
            .on('data', (data) => results.push(data))
            .on('end', async () => {
              // Process data and create summary
              const summary = {
                totalRecords: results.length,
                processedAt: new Date().toISOString()
              };


              // Upload processed results
              await yepcode.storage.upload(
                "outputs/summary.json",
                new Blob([JSON.stringify(summary, null, 2)], { type : 'application/json' })
              );


              resolve(summary);
            });
        });
      }
      module.exports = { main };`,
      {
        onLog: (log) =>
          console.log(`${log.timestamp} ${log.level}: ${log.message}`),
        onFinish: (returnValue) =>
          console.log("Processing finished:", returnValue),
        onError: (error) => console.error("Error:", error),
      }
    );


    await execution.waitForDone();


    // 3. Download the processed results
    const resultStream = await storage.download("outputs/summary.json");
    resultStream.pipe(fs.createWriteStream("./processed-summary.json"));


    console.log("Workflow completed!");
  }


  processData();
  ```

* Python

  ```py
  from yepcode_run import YepCodeRun, YepCodeStorage, YepCodeApiConfig


  runner = YepCodeRun(
      YepCodeApiConfig(
          api_token="<your-api-token-here>"
      )
  )
  storage = YepCodeStorage(
      YepCodeApiConfig(
          api_token="<your-api-token-here>"
      )
  )




  def process_data():
      # 1. Upload input file
      with open("data.csv", "rb") as f:
          storage.upload("inputs/data.csv", f)


      # 2. Execute code that processes the file
      execution = runner.run(
          """def main():
          import pandas as pd
          import json
          import io


          # Download and process the CSV
          content = yepcode.storage.download("inputs/data.csv")
          df = pd.read_csv(io.BytesIO(content))


          # Process data and create summary
          summary = {
              "totalRecords": len(df),
              "processedAt": pd.Timestamp.now().isoformat()
          }


          # Upload processed results
          summary_json = json.dumps(summary).encode()
          yepcode.storage.upload("outputs/summary.json", io.BytesIO(summary_json))


          return summary""",
          {
              "onLog": lambda log: print(f"{log.timestamp} {log.level}: {log.message}"),
              "onFinish": lambda return_value: print(
                  "Processing finished:", return_value
              ),
              "onError": lambda error: print("Error:", error),
          },
      )


      execution.wait_for_done()


      # 3. Download the processed results
      content = storage.download("outputs/summary.json")
      with open("processed-summary.json", "wb") as f:
          f.write(content)


      print("Workflow completed!")




  process_data()
  ```

### Putting it together: safe agent workflows

An end‑to‑end pattern we recommend for agentic systems:

1. **Upload inputs to Storage** (e.g., CSV, PDF, prompt context files).
2. **Generate code** with your LLM (JS or Python) to process those inputs.
3. **Execute with YepCode Run** in an isolated sandbox; capture logs and return values.
4. **Persist outputs to Storage** (artifacts, JSON summaries, charts) for downstream tools.
5. **Audit and retry** with full logs; iterate safely without exposing your host.

This approach gives you the flexibility of dynamic, LLM‑generated code with the safety of ephemeral, resource‑limited sandboxes—and predictable file I/O.

## Why this matters now

As agents take on higher‑impact tasks, the execution surface becomes an organizational risk. Following secure‑by‑default patterns—sandboxed execution and controlled file I/O—lets you ship faster without compromising safety.

If you’re exploring AI Agent platforms like Smolagents, Autogen, CrewAI, or event no-code tools agents like n8n, zapier or make, keep going—and consider using YepCode Run as your execution plane plus YepCode Storage for reliable I/O. You’ll get modern developer ergonomics with security that scales.