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

# Run Devin Outposts on Tensorlake Sandboxes

> Serve Devin Outposts sessions on Tensorlake sandboxes. Devin runs the agent loop; every command, file edit, and repo checkout runs in a Firecracker microVM you control.

[Devin Outposts](https://docs.devin.ai/cloud/outposts) lets you run Devin sessions inside infrastructure you control. The agent loop stays in Cognition's cloud. The session machine, where commands run, files change, and repos get checked out, moves into a Tensorlake sandbox you own.

Use an outpost when the agent needs a custom environment: private CA certificates, preinstalled toolchains, pre-cloned repositories, or services only reachable from your network, all defined in the Tensorlake image and sandbox configuration. And because Tensorlake can run on self-hosted compute, the sandboxes can sit inside your network, where Devin can read your source code, query your databases, and test against the systems it is writing code for.

An **orchestrator** watches Devin's session queue, claims each session, and runs it in a Tensorlake sandbox. The orchestrator itself runs inside a long-lived Tensorlake sandbox, so no long-running process stays on your laptop. When a session goes idle the sandbox suspends; when it wakes the same sandbox resumes; when it ends the sandbox is terminated. Each Devin session maps to one sandbox.

```mermaid theme={null}
graph LR
    D["Devin cloud<br/>agent loop + session queue"]
    O["Orchestrator<br/>one per outpost, runs in a Tensorlake sandbox"]
    S["Tensorlake sandbox<br/>one per session, runs devin-remote<br/>(Devin's session agent binary)"]

    O <-->|"watch · claim · release"| D
    O -->|"create · suspend · resume · launch remote"| S
    S -->|"outbound connection"| D
```

## Prerequisites

* A Devin account with Outposts enabled, and an org admin who can connect the outpost.
* A Tensorlake account and API key from [cloud.tensorlake.ai](https://cloud.tensorlake.ai).
* Python 3.10+ on the machine that runs the setup and launcher commands. The orchestrator itself runs inside a Tensorlake sandbox.

Tensorlake sandboxes are Linux microVMs, so the outpost is Linux only. Run one orchestrator per outpost.

## Setup

The reference implementation is [tensorlakeai/devin-outposts-tensorlake](https://github.com/tensorlakeai/devin-outposts-tensorlake), a Python package that is mainly the orchestrator. Installing it also provides the CLI commands used in the steps below: `outposts-connect`, the two image builders, for orchestrator and session sandboxes respectively, and the sandbox launcher.

<Steps>
  <Step title="Install">
    ```bash theme={null}
    git clone https://github.com/tensorlakeai/devin-outposts-tensorlake.git
    cd devin-outposts-tensorlake
    python3 -m venv .venv && . .venv/bin/activate
    pip install -e .
    cp .env.example .env
    ```

    Add your `TENSORLAKE_API_KEY` to `.env`.
  </Step>

  <Step title="Connect the outpost">
    Run this on the same machine as your browser:

    ```bash theme={null}
    outposts-connect --platform linux
    ```

    `outposts-connect` is the package's local implementation of [Devin's partner connection flow](https://docs.devin.ai/cloud/outposts/partners). It opens Devin's connection page, where a Devin org admin confirms the outpost and clicks **Connect**. The browser returns a one-time code to a temporary listener on `localhost`, which is why the command and browser must share a machine. The command exchanges the code for a machine-serving token and writes `DEVIN_OUTPOSTS_TOKEN`, `DEVIN_API_URL`, and `OUTPOST_ID` to `.env`. The token never passes through the browser.

    This one-time authorization creates the outpost and a service user whose token the orchestrator uses for every queue call. The outpost then appears in Devin's environment picker whenever someone in your org creates a session.

    For headless hosts or manual outpost creation, see [manual setup in the repo README](https://github.com/tensorlakeai/devin-outposts-tensorlake#manual-outpost-setup).
  </Step>

  <Step title="Build the session image">
    ```bash theme={null}
    set -a && . ./.env && set +a
    build-devin-outposts-image
    ```

    This builds an image with the remote's required system packages: `git`, `curl`, and CA certificates. It also tries to install the GitHub CLI and Chromium, but those steps are best-effort; if your sessions depend on either tool, verify the built image. Devin also lists `ffmpeg` as an optional dependency for screen recording; this image skips it, so add it to the build recipe if you want recordings. Copy the printed name into `IMAGE_NAME` in `.env`.
  </Step>

  <Step title="Build the orchestrator image">
    ```bash theme={null}
    set -a && . ./.env && set +a
    build-devin-outposts-dispatcher-image
    ```

    This packages the orchestrator itself into its own image, distinct from the session image that serving sandboxes boot from. Build it once; rebuild only when you update the package. (The repo calls this the dispatcher image.)
  </Step>

  <Step title="Launch the orchestrator">
    ```bash theme={null}
    set -a && . ./.env && set +a
    devin-outposts-orchestrator-sandbox
    ```

    This starts the orchestrator inside a long-lived Tensorlake sandbox. The command is idempotent: run it again and it resumes the sandbox and re-ensures the orchestrator process. The orchestration work now happens in the sandbox, not on your local; the only local piece left is a small keep-alive cron, covered in [Operate the orchestrator](#operate-the-orchestrator).

    The launcher reads your local `.env` and injects the credentials the orchestrator needs (`TENSORLAKE_API_KEY`, the Devin machine token, and `GIT_TOKEN` if set) into the orchestrator process's environment at start. They are never baked into the orchestrator image. Treat this sandbox as a trusted control-plane host; session sandboxes never receive the machine token, each remote gets only its own session's connect token. To rotate a credential, update `.env`, then `--terminate` and relaunch.
  </Step>

  <Step title="Create a session">
    Confirm the orchestrator is watching, then create a session in the Devin UI or Slack and select your outpost. The orchestrator claims it and runs it in a sandbox.

    ```bash theme={null}
    devin-outposts-orchestrator-sandbox --status
    ```

    Each claim pins `devin-remote`, Devin's session binary, by SHA; the orchestrator downloads it into the sandbox and verifies the checksum before executing it. The binary dials out to Devin's gateway over HTTPS, so the sandbox needs no inbound ports.

    Session credentials follow the same injected-at-start pattern as the orchestrator's. The claim response carries that session's connect token and gateway URL, which the orchestrator sets as environment variables when it launches `devin-remote` in the sandbox. If `REPOS` is set, the orchestrator pre-clones those repositories into the sandbox first, passing `GIT_USERNAME` and `GIT_TOKEN` to the clone command only. Nothing is baked into the session image, and the session sandbox never receives your Tensorlake API key or the Devin machine token.
  </Step>
</Steps>

## Operate the orchestrator

Observe and manage the orchestrator sandbox from your machine:

```bash theme={null}
devin-outposts-orchestrator-sandbox --status
devin-outposts-orchestrator-sandbox --logs
devin-outposts-orchestrator-sandbox --terminate
```

Outposts is watch-based, so the orchestrator runs continuously (not scale-to-zero). Tensorlake suspends a named sandbox after your plan's maximum idle window, and a suspended orchestrator cannot claim sessions. The launcher is idempotent (it resumes the sandbox and re-ensures the orchestrator process), so schedule it on a cron to keep it watching across that window:

```bash theme={null}
# crontab -e: resume the orchestrator sandbox if it suspended
*/15 * * * * cd /path/to/devin-outposts-tensorlake && set -a && . ./.env && set +a && .venv/bin/devin-outposts-orchestrator-sandbox
```

The cron host needs the repo, the venv, and `.env`, and it needs to be awake when the tick fires, so an always-on machine (a small server or any host that does not sleep) is the better home for it. A laptop works too, with one caveat: while the laptop sleeps the orchestrator can stay suspended, and queued sessions wait until the next tick after it wakes. Keep the interval shorter than your plan's idle window.

## Watch session logs

The orchestrator log (`--logs`) shows lifecycle events only (claim, sandbox created, serving, released). The session's processing output, every tool call `devin-remote` executes, is written inside the serving sandbox to `/tmp/devin-outposts/<session>.log`. The reference implementation includes `session_logs.py`, a helper script we wrote to monitor session logs from your machine:

```bash theme={null}
python session_logs.py                 # list this outpost's serving sandboxes
python session_logs.py <dvo-name>      # dump the last 500 lines
python session_logs.py <dvo-name> -f   # stream live (ctrl-C to stop)
```

The sandbox name is the `dvo-...` string the orchestrator logs when it claims a session (visible in `--logs`). Live mode runs `tail -F` in the sandbox over a PTY websocket (the SDK's streaming channel) and follows the session lifecycle: it reconnects if the connection idles out, waits while the sandbox is suspended (Devin put the session to sleep) and re-attaches on resume, and exits when the sandbox is terminated because the session ended.

## Configuration

Set these in `.env`. `outposts-connect` writes the Devin values, you add `TENSORLAKE_API_KEY` during install, and the image build prints `IMAGE_NAME`; the rest have defaults.

| Variable                                                 | Required | Purpose                                                                                                                                                                       |
| -------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DEVIN_OUTPOSTS_TOKEN`                                   | Yes      | Machine-serving token for queue watch/claim/release.                                                                                                                          |
| `DEVIN_API_URL`                                          | No       | Devin API base without `/opbeta`. Defaults to `https://api.devin.ai`; `outposts-connect` writes it.                                                                           |
| `TENSORLAKE_API_KEY`                                     | Yes      | Authenticates the Tensorlake SDK for images and sandbox lifecycle.                                                                                                            |
| `OUTPOST_ID`                                             | Yes      | Your outpost.                                                                                                                                                                 |
| `IMAGE_NAME`                                             | Yes      | Image the orchestrator boots sandboxes from.                                                                                                                                  |
| `MAX_CONCURRENT_SESSIONS`                                | No       | Concurrent sessions (default `5`).                                                                                                                                            |
| `SANDBOX_CPUS` / `SANDBOX_MEMORY_MB` / `SANDBOX_DISK_MB` | No       | Per-session sizing (2 vCPU, 8 GiB, 10 GiB).                                                                                                                                   |
| `SANDBOX_TIMEOUT_SECS`                                   | No       | Idle seconds before auto-suspend (default `1800`).                                                                                                                            |
| `REPOS` / `GIT_USERNAME` / `GIT_TOKEN`                   | No       | Comma-separated clone URLs to pre-clone into each sandbox, and credentials for private ones. The credentials are passed to the clone command only, never stored in the image. |

## Next steps

<CardGroup cols={2}>
  <Card title="Reference implementation" icon="github" href="https://github.com/tensorlakeai/devin-outposts-tensorlake">
    The full orchestrator and the CLI commands that drive it.
  </Card>

  <Card title="Sandbox lifecycle" icon="arrows-rotate" href="/sandboxes/lifecycle">
    The suspend/resume model that keeps idle sessions cheap.
  </Card>

  <Card title="Sandbox images" icon="layer-group" href="/sandboxes/images">
    Build a custom session image with your toolchain.
  </Card>

  <Card title="Claude Managed Agents" icon="robot" href="/sandboxes/claude-managed-agents">
    The same orchestrator pattern for Anthropic's managed agents.
  </Card>
</CardGroup>
