intentic
Create your workspace
Run a sandbox

Quickstart

Sign in once, then bring a sandbox up on your own machine whichever way you prefer: a desktop app, one setup command, a Compose file you read first, or plain docker run. All four produce the same sandbox.

On this page(10 sections)

What you need

  • A machine that stays on while the agent works: a laptop, a desktop, or a VPS.
  • Docker Engine on Linux, WSL2 or macOS. The app and the setup command install it if missing, both asking first; the Compose and docker run paths assume you already have it.
  • A Google account to sign in. No card, no repo permissions, no code upload.

No inbound ports, on any path. The sandbox is reached over a private tunnel that dials out from your machine, so nothing is exposed and nothing is deployed.

All four paths below put the sandbox on a machine you own. It can also run on a machine we host:compare the two if you have not chosen yet.

1 · Sign in and get your setup code

Open app.intentic.dev and sign in with Google. A sandbox is created as setup opens, named for you and renameable from the same card, so its address under intentic's own domain is ready straight away. No account anywhere else, and nothing to configure.

You never type the setup code, and there is nothing to generate. The moment your address is ready, the setup screen's Run it step shows a finished command with the code in it, behind a Copy button. One tab per install path, so the line you copy is the one your machine needs:

On the setup screenWhat Copy gives you
Linux / macOSThe curl … | sh -s -- <your code> line, ready to paste into a terminal
WindowsThe PowerShell line, with the code already set as an environment variable
Docker ComposeYour two services, plus the bootstrap whose code=… is your setup code
Run on this computerNothing to copy: the button hands the code straight to the installed desktop app

That is the whole of step 1. The code expires 30 minutes after the screen creates it; reopen the setup screen for a fresh one, losing nothing. More about setup codes has the rest.

Throughout, the platform stores your identity and your sandbox's URL, nothing else. It never sees your code or keys.

2 · Pick how you install it

Four routes to the same result. Pick by how much you want to type, and how much you want to read first.

PathChoose it whenYou run
Desktop appYou'd rather not open a terminal at all, and you want updates as a button.An installer, then one click
Setup commandYou're on a server, a Mac, or anywhere over SSH. The fastest path.One pasted line
Docker ComposeYou want to read the whole definition before anything starts, or you already run a Compose stack.docker compose up -d
Plain docker runYou're scripting this into your own tooling and want no intentic script in the loop.Five docker commands

Nothing binds you to the one you pick: every path uses the same container, volume and network names, so a sandbox can move between them later without losing /work: see Docker setup for the anatomy they all share.

Install with the desktop app

The no-terminal path, and the one that keeps paying off: a sandbox can never recreate its own container, so without the app every update and rebuild is a command you paste on the host. In the app it is a button.

Install it, sign in, and click Run on this computer on the setup card. There is no code to copy: the click hands the app your setup code, and the app installs Docker if the machine has none, starts the sandbox and its tunnel, and opens your workspace when it answers.

Afterwards it stays in your tray to start, stop, update, rebuild and remove the sandbox, and to show its logs. It is not a second product: it runs the very same setup script the pasted command runs, and you can still reach the same sandbox from any browser at app.intentic.dev. Removing the app removes only the app; your sandbox, its files and its history stay in Docker until you remove them. More on the download page.

Install with the setup command

Run it on the machine that should host the sandbox. The setup screen shows the line with your code in it.

Linux / macOS
# Linux / macOS. Setup shows this line with your own code filled in.
curl -fsSL https://intentic.dev/connect | sudo sh -s -- <SETUP_CODE>

# Already have Docker? Drop the sudo: it is only ever there to install it.
curl -fsSL https://intentic.dev/connect | sh -s -- <SETUP_CODE>
Windows · PowerShell
# Windows (PowerShell)
$env:SETUP_CODE='<SETUP_CODE>'; irm https://intentic.dev/connect.ps1 | iex

The sudo is for installing Docker and nothing else. Every other step is a docker or curl call your own user can make, so drop it on a machine that already has Docker. That is what the I already have Docker switch on the setup page does to the command it shows you. Run it without sudo on a machine with no Docker and it stops, naming your two options rather than escalating on its own.

The script itself is short and readable before you pipe it anywhere: intentic.dev/connect. It handles the one step needing a dependency-free start: getting Docker onto the machine, after asking, then fetches the ic CLI and hands over to it. Re-running the same line upgrades that CLI in place.

Variations
# Also make this machine a deploy target for the agent (its own Cloudflare tunnel).
curl -fsSL https://intentic.dev/connect | sudo env SELF_HOST=1 CF_TOKEN=<CF_TOKEN> sh -s -- <SETUP_CODE>

# Unattended (no terminal to ask): pre-consent to the Docker install.
curl -fsSL https://intentic.dev/connect | sudo env INSTALL_DOCKER=1 sh -s -- <SETUP_CODE>

For a scripted install with no setup code at all, pass the values directly instead: CONNECT_TOKEN=… SANDBOX_GRANT=… ./connect.sh.

Install with Docker Compose

The path for someone who would rather read a file than run a script: nothing executes on your machine until you start it yourself. Setup's Docker Compose tab renders this service with your hostname and client id filled in; paste it into your own docker-compose.yml.

docker-compose.yml
services:
    intentic-sandbox:
        image: ghcr.io/intentic/sandbox:stable
        pull_policy: always
        container_name: intentic-sandbox-<SLUG>
        init: true
        cap_add: [SYS_ADMIN, SYS_PTRACE]
        restart: unless-stopped
        dns: [1.1.1.1, 1.0.0.1]
        extra_hosts: [host.docker.internal:host-gateway]
        networks:
            intentic:
                aliases: [intentic-sandbox-workspace]
        logging:
            driver: json-file
            options: { max-size: 10m, max-file: "3" }
        ports: ["127.0.0.1:${LOCAL_PORT}:8788"]
        volumes:
            - work:/work
            - history:/history
            - docker-engine:/var/lib/docker
        environment:
            CONNECT_TOKEN: ${CONNECT_TOKEN:?run the .env bootstrap first}
            OWNER_EMAIL: ${OWNER_EMAIL:-}
            SANDBOX_PUBLIC_URL: https://<SLUG>.intentic.dev
            PLATFORM_URL: https://api.intentic.dev
            GOOGLE_CLIENT_ID: <shown filled in on the setup page>
            INGRESS_URL: ${INGRESS_URL:-}
            SANDBOX_GRANT: ${SANDBOX_GRANT:?run the .env bootstrap first}
networks:
    intentic:
        name: intentic-workspace-<SLUG>
volumes:
    work:
        name: intentic-workspace-<SLUG>
    history:
        name: intentic-history-<SLUG>
    docker-engine:
        name: intentic-docker-<SLUG>

Then, once, in the same folder: the same tab prints this with your setup code already in the URL:

Bootstrap
# In the folder holding your docker-compose.yml: run once.
curl -fsS https://api.intentic.dev/setup/claim -d code=<SETUP_CODE> > .env
docker compose up -d

The first command redeems your setup code into the .env that Compose interpolates (CONNECT_TOKEN, the SANDBOX_GRANT that makes the box reachable, INGRESS_URL, LOCAL_PORT, OWNER_EMAIL). After that the sandbox is yours to manage with docker compose up -d, down, and logs. Your workspace lives in the named volumes, so down then up keeps it.

Two things this path leaves out on purpose. The docker capability's nested engine needs privileged: true, which stays your own edit: the rebuild flow recreates containers with docker run and would fight a Compose-managed one. And desktop sync isn't connected here; turn it on from its card once your workspace opens.

Install with a plain docker run

No intentic script in the loop, which suits folding this into your own provisioning tooling. One rule makes it safe: ask the image what its run command is instead of writing the flags yourself. The container's shape (its capability posture, volumes, network alias, environment allowlist) ships with the image and changes with it, so a flag list copied into your scripts today is a sandbox quietly missing something next release.

Setup has no tab for this one, so fill in the three values yourself. Your slug is the first label of your sandbox's hostname. Your setup code is the trailing argument of the Linux/macOS command on the setup screen, or the code= value in its Compose bootstrap.

Your machine · bash
IMAGE=ghcr.io/intentic/sandbox:stable
SLUG='<SLUG>'              # the first label of your sandbox hostname
SETUP_CODE='<SETUP_CODE>'  # the short-lived code the setup screen shows

# 1 · Redeem the setup code. You get KEY=value lines: CONNECT_TOKEN, SANDBOX_GRANT,
#     INGRESS_URL, SANDBOX_HOSTNAME, OWNER_EMAIL, LOCAL_PORT.
#     Every other path does exactly this.
curl -fsS https://api.intentic.dev/setup/claim -d code=$SETUP_CODE > sandbox.env

# 2 · Add the three the claim does not carry (the setup page's Compose tab shows the
#     client id filled in).
cat >> sandbox.env <<EOF
SANDBOX_PUBLIC_URL=https://$SLUG.intentic.dev
PLATFORM_URL=https://api.intentic.dev
GOOGLE_CLIENT_ID=<shown filled in on the setup page>
EOF

# 3 · The network the sandbox and anything you run beside it share.
docker network create intentic-workspace-$SLUG

# 4 · Ask the image for its own run command, then read it, then run it.
docker pull $IMAGE
RUN=$(tr '\n' '\0' < sandbox.env | docker run -i --rm --entrypoint intentic $IMAGE \
    sandbox run-command --slug $SLUG --image $IMAGE --base-image $IMAGE \
    --channel stable --dns "1.1.1.1 1.0.0.1")
echo "$RUN"
eval "$RUN"

# That is all of it. The sandbox connects itself outward on boot. There is no
# second container: the daemon dials the tunnel itself.

Step 4 is the whole idea: sandbox run-command reads your environment on stdin and prints the complete, correctly quoted docker run line. Print it, read it, run it, and your tooling keeps working against future images unchanged. The line names the container intentic-sandbox-<slug>, mounts the three named volumes, grants SYS_ADMIN and SYS_PTRACE and nothing else, and publishes only a loopback port. Every field of it is explained on Docker setup.

If docker run fails because the loopback port is already taken, re-run step 4 with --no-local-publish. That port is only a shortcut for a browser on the same machine; the sandbox works over its tunnel without it.

3 · Check what came up

Whichever path you took, you now have one container and nothing else:

  • the sandbox: the daemon, your agent, and your workspace, running unprivileged;
  • inside it, a small tunnel agent that dials out to make the daemon reachable.

Both halves are outbound-only: no port is opened on your machine. The daemon announces its URL, your browser probes the sandbox directly until it reports healthy, and the workspace opens on its own. From then you are talking to the daemon over its tunnel and the platform is out of the loop.

More about setup codes

Wherever a command above reads <SETUP_CODE>, the real one is filled in on the setup screen. If you are building the command yourself, the docker run path has no tab of its own. The code is the trailing argument of the Linux/macOS line, or the code= value in the Compose bootstrap.

Within its 30 minutes the code is redeemed on your machine for the real connection token. That is why no long-lived secret lands in your shell history, and why re-running the command still works.

Setting up on a different machine from the one you're reading this on? On a phone, setup offers to email you the link back to this screen: open it on the target machine and copy the command there.

After it's running

You can run several sandboxes at once for different workspaces, roles or trust boundaries, and each sandbox can run many agents. They coexist on the same machine without stepping on each other. Docker setup covers what was created and how to update, rebuild, and remove it; Architecture covers why the pieces are split the way they are.

More in Run a sandbox

Type to search every page, in the docs and the API reference.