> ## Documentation Index
> Fetch the complete documentation index at: https://docs.genesiscomputing.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Azure Sandboxes

> Run the code Genesis agents write in Azure Container Instances in your own Azure subscription. No inbound ports, deleted when the work is done.

## What an Azure sandbox is

When a Genesis agent needs to run code, such as a Python analysis, a shell script or a
`pip install`, it runs it in a **sandbox**: a short-lived, isolated container that is separate from
Genesis itself. An **Azure sandbox** is a sandbox that runs in **Azure Container Instances
(ACI)**, in a resource group in **your own Azure subscription**.

* **Your cloud, your bill.** The container runs in the subscription and resource group you
  choose. Azure bills you for it directly, per second, only while it runs.
* **One container per sandbox.** Each sandbox is one ACI container group with one Linux
  container. The agent starts it, runs commands, installs packages, moves files in and out, and
  deletes it when it is done.
* **No inbound ports.** The container gets no public IP address and no open ports. Genesis
  reaches it only through Azure's own authenticated management and command services.
* **Cleaned up automatically.** Stopping a sandbox deletes its container group. If nobody
  stops it, Genesis stops it after it has been idle for its idle timeout, and the container
  exits on its own when it reaches its maximum lifetime, even if Genesis is down.
* **A narrowly scoped identity.** Genesis signs in to Azure as a service principal that you
  create and that can act only on the one resource group you give it.

## When to use it

| Your situation | Choose |
| - | - |
| Your organization runs on Azure and has no AWS account (for example, Snowflake on Azure) | **Azure sandboxes** |
| Your security team wants agent-written code to run in your own cloud account, not on the Genesis host | **Azure sandboxes** |
| You already run Genesis sandboxes on Amazon EKS, Kubernetes or Railway | Keep using those; see [Sandbox Sessions](/docs/User-Guide/Sandbox-Sessions) |

Azure sandboxes work with every way of running Genesis: the Snowflake Native App, Docker,
Kubernetes and virtual machines. The only difference between them is how you allow Genesis's
outbound network traffic; see [Network access](/docs/Setup/Azure-Sandboxes-Setup#allow-genesis-to-reach-azure).

## How it works

```mermaid theme={null}
flowchart LR
  U["You, in a Genesis chat"] --> G["Genesis agent"]
  G -->|"1. sign in, HTTPS 443"| E["Microsoft Entra ID<br/>login.microsoftonline.com"]
  G -->|"2. create, check, delete, HTTPS 443"| A["Azure Resource Manager<br/>management.azure.com"]
  G -->|"3. run commands, port 19390"| X["ACI exec endpoint<br/>region.atlas.cloudapp.azure.com"]
  subgraph SUB["Your Azure subscription"]
    subgraph RG["Your sandbox resource group"]
      C["Container group<br/>genesis-sbx-..."]
    end
  end
  A --> C
  X --> C
  C -->|"outbound internet, e.g. pip install"| I[(Internet)]
```

1. **You ask.** You ask a Genesis agent for something that needs code, for example "compute
   month-over-month growth by store and give me a CSV". The agent decides to use an Azure
   sandbox, or you ask for one by name.
2. **Genesis signs in to Azure.** Genesis uses your saved Azure connection to get a short-lived
   access token from Microsoft Entra ID for the service principal.
3. **Genesis creates the container.** Genesis asks Azure Resource Manager to create a container
   group named `genesis-sbx-<random>` in your resource group and region, and waits until it is
   running. With the default image this takes about 25 to 30 seconds.
4. **The agent works in it.** Each command runs through Azure's container exec service. Genesis
   connects out to an Azure exec endpoint for the region on port **19390**, sends the command,
   and reads back the output. Each command adds about two seconds of overhead on top of its own
   run time. Files and installed packages stay in the container between commands.
5. **The agent brings results back.** Command output comes back to the chat, and the agent can
   download files the code wrote, such as a CSV or a chart.
6. **The sandbox is deleted.** When the work is done, the agent stops the sandbox and Genesis
   deletes the container group. Everything inside it is gone.

<Note>
  The sandbox does not receive your Snowflake or other Genesis credentials by default. When the
  work needs your data, the agent queries it with Genesis's own connection, then uploads the
  result into the sandbox, for example as a CSV file. The code in the sandbox works on that copy.
</Note>

### What runs where

| Component | Runs in | Billed by |
| - | - | - |
| Genesis and its agents | Wherever you run Genesis (Snowflake Native App, Docker, Kubernetes, VM) | As today |
| The sandbox container | Azure Container Instances, in your subscription and resource group | Azure, on your subscription |
| The container image | Pulled by Azure from Microsoft Container Registry by default, or from your own registry | Your registry, if you use your own |

Azure Container Instances bills per second for the vCPU and memory a container group uses while
it runs. See [Azure Container Instances pricing](https://azure.microsoft.com/pricing/details/container-instances/)
for current prices in your region. By default each sandbox uses **1 vCPU and 1.5 GB of memory**.

## Lifecycle and cost safety

A sandbox you forget about should not keep costing money. Several independent safeguards stop it:

| Safeguard | What it does | Works when Genesis is down? |
| - | - | - |
| **Stop** | The agent (or you, from the Sandbox Sessions page) stops the sandbox. Genesis deletes the container group. | No |
| **Idle timeout** | Genesis's sandbox monitor stops a sandbox that has had no activity for its idle timeout. An agent can set the idle timeout when it starts the sandbox; if it does not, the sandbox gets 30 minutes. | No |
| **Maximum lifetime** | The container's main process is a timer for the session's maximum lifetime (8 hours unless the agent sets another). When it ends, the container exits, Azure does not restart it, and compute billing stops. The sandbox monitor also stops sessions that pass their maximum lifetime. | **Yes** |
| **Restart recovery** | When Genesis restarts, it reattaches to Azure sandboxes that are still running, and deletes container groups that have already ended. If a delete fails, Genesis keeps the record and tries again later. | Runs at restart |

A container group whose container has exited no longer bills for compute, but it still exists in
your resource group, and still counts against your region's Container Instances quota, until it
is deleted. Genesis deletes it the next time its monitor runs or when Genesis restarts. Every
container group Genesis creates is tagged `genesis-sandbox: true`, so you can find any that
remain:

```bash theme={null}
az container list --resource-group genesis-sandboxes \
  --query "[?tags.\"genesis-sandbox\"=='true'].{name:name, provisioning:provisioningState}" -o table
```

<Note>
  Administrators can turn timeout enforcement for Azure sandboxes off with the deployment setting
  `jobs.sandbox_monitor.enforce_azure` (default `true`). Leave it on unless you have your own
  cleanup in place. The maximum-lifetime timer in the container applies either way.
</Note>

## Security model

* **A scoped principal.** Genesis acts in Azure as a service principal that you create. Grant it
  **Contributor** on the sandbox resource group only, or, for least privilege, a custom role with
  exactly the five permissions Genesis uses; see
  [Least-privilege role](/docs/Setup/Azure-Sandboxes-Setup#least-privilege-alternative-custom-role).
  It cannot see or change anything outside that resource group.
* **An encrypted secret that stays in Genesis.** The client secret is stored as an encrypted
  Genesis secret. Genesis uses it only to request short-lived Azure access tokens. It is never
  passed into the sandbox container.
* **Access follows the person asking.** An agent can use an Azure connection only when the user
  it is working for, and the agent itself, are allowed to use that connection. Genesis checks this
  on every start, the same way it does for every other connection. Agents cannot supply their own
  Azure credentials when they start a sandbox: Genesis refuses a start that carries a tenant ID,
  client ID or client secret instead of a saved connection, so every sandbox can be found,
  reattached and deleted later as the same identity.
* **Each sandbox stays where it was created.** A sandbox is bound, when it starts, to the
  connection, subscription, resource group and region it was created in. Editing the connection
  later does not move or redirect sandboxes that already exist.
* **No inbound network access.** The container group has no public IP address and no exposed
  ports. Commands reach it only through Azure's authenticated exec service, using a one-time
  session Genesis requests from Azure Resource Manager for each command.
* **Outbound internet is on by default.** Like any Container Instances container, the sandbox can
  reach the internet, which is what lets the agent `pip install` packages. To control where it can
  go, attach it to a subnet in your own virtual network and apply your network rules there; see
  [Virtual network](/docs/Setup/Azure-Sandboxes-Using#run-inside-your-virtual-network).
* **Environment values stay hidden.** Environment variables Genesis passes to the container are
  sent as Azure secure values, so they do not appear in the Azure portal or in Azure Resource
  Manager responses.
* **Results are checked end to end.** Each command and its output are carried with a checksum
  computed inside the container, so a command is never run, and output is never returned, if it
  was damaged on the way.

## Limits

* **Linux containers only.** Windows containers are not supported.
* **Any Azure region that offers Container Instances.** Each connection uses one region. To run
  sandboxes in two regions, create two connections.
* **Start time.** About 25 to 30 seconds with the default image. Larger custom images take
  longer to pull. Genesis waits up to 10 minutes for a sandbox to start.
* **Command overhead.** About two seconds per command, on top of its own run time. Ask the agent
  to put related steps in one script rather than running many tiny commands.
* **Size.** 1 vCPU and 1.5 GB of memory by default. Larger sizes are available within the limits
  Container Instances allows in your region and your subscription's quota.
* **Not yet tested at launch.** Attaching sandboxes to a virtual network subnet and pulling images
  from a private registry are supported, but were not tested end to end at launch. Try them in a
  non-production resource group first.

## Next steps

<CardGroup cols={2}>
  <Card title="Set up Azure sandboxes" icon="screwdriver-wrench" href="/docs/Setup/Azure-Sandboxes-Setup">
    Prepare your Azure subscription, create the Genesis connection, and allow network access.
  </Card>

  <Card title="Use Azure sandboxes" icon="terminal" href="/docs/Setup/Azure-Sandboxes-Using">
    Prompts to try, what to expect, images, sizes and options.
  </Card>

  <Card title="Troubleshooting" icon="wrench" href="/docs/Setup/Azure-Sandboxes-Troubleshooting">
    Every error message, what causes it, and how to fix it.
  </Card>

  <Card title="Sandbox sessions" icon="box" href="/docs/User-Guide/Sandbox-Sessions">
    See, stop and clean up running sandboxes from the Genesis UI.
  </Card>
</CardGroup>
