Droid
Start from Tenki's pre-built Droid image and run Factory's coding agent headlessly with droid exec.
Tenki's public tenki/droid:stable image starts from the standard sandbox base image and adds Factory's Droid coding agent (the droid command) plus the droid-smoke command for the API-key path. No credential is baked into the image. Droid authenticates from a FACTORY_API_KEY that you pass per session and that it reads straight from the session environment, so a session can start and finish unattended, or from a device-code login with your Factory account. Sandbox usage is programmatic, so you drive droid headlessly with droid exec.
Droid: Factory's coding agent in your sandbox
Droid is Factory's terminal coding agent. Alongside its interactive mode it has droid exec, a non-interactive mode built for scripts and automation: it takes a prompt, does the work, and exits. That is the mode a sandbox uses, and it pairs with a disposable, isolated Linux VM you create and terminate per task, so an agent has somewhere to run real commands without touching your own machine.
Start a session with an API key
Create a Factory API key (it has the form fk-...), export it locally, then pass it only to the session:
export FACTORY_API_KEY=<your-factory-api-key>
tenki sandbox create \
--image tenki/droid:stable \
--env "FACTORY_API_KEY=$FACTORY_API_KEY" \
--name droid-demoThe shell history contains the environment variable reference, not the key value. Do not add the key to a template, snapshot, source file, or image.
Run the built-in connectivity check:
tenki sandbox exec --session droid-demo -- droid-smokedroid-smoke runs one headless droid exec with your FACTORY_API_KEY, at the default read-only autonomy, and checks that the model echoes a sentinel token back. A successful result looks like:
TENKI_SANDBOX_OKdroid-smoke exits 2 when FACTORY_API_KEY is unset, and 1 when the headless run fails (including a timeout) or the reply is missing the token.
Terminate the Tenki session when you finish:
tenki sandbox terminate droid-demoStart a session with a device-code login
Use this path to sign in with your Factory account instead of passing an API key. Create the session with no key:
tenki sandbox create --image tenki/droid:stable --name droid-demoDroid has no login subcommand; it signs in from its interactive mode, which needs a real terminal. Open one over SSH and start droid:
tenki sandbox ssh droid-demo
droidWith no credentials, droid opens on a Login prompt (inside a running droid session, use /login). It prints a device URL on auth.factory.ai and a code. Open that URL on your own machine, enter the code, and droid is signed in for the life of the session. Exit droid and SSH; droid exec then runs with no FACTORY_API_KEY set.
If a session has both, FACTORY_API_KEY takes precedence over the stored login.
Run a headless task
Drive droid programmatically with droid exec, which runs a single prompt and exits. For anything beyond it, run droid exec --help inside the session.
# One-shot task against the working directory inside the session
tenki sandbox exec --session droid-demo -- droid exec "summarize this repo's build setup"
# Against your own project: clone it into the session first, then run droid inside it
tenki sandbox exec --session droid-demo -- \
bash -lc "git clone https://github.com/your-org/your-repo /home/tenki/work && cd /home/tenki/work && droid exec 'list the top-level modules and how they build'"Both run at the default read-only autonomy. To let droid edit files or run commands, raise the level as described below.
Droid can also call your own model provider keys (BYOK) through custom models in its settings; see Factory's BYOK docs. BYOK changes which provider droid calls, not how droid authenticates: a Factory login or FACTORY_API_KEY is still required.
Autonomy levels
droid exec controls what the agent may do on its own through an autonomy level, and it defaults to read-only. Droid enforces this itself, before anything runs:
- default (no flag): read-only. Droid reads files, inspects state, and runs read-only commands (
ls,cat,git status,git diff), but makes no changes. --auto low: adds basic file operations in non-system directories (create, move, copy). No package installs and no system changes.--auto medium: adds recoverable development actions, such as installing packages withoutsudo, network requests, local git commits, and builds. Nogit pushand nosudo.--auto high: adds actions with real side effects, such as running downloaded scripts,git push, deployments, and migrations. Droid's own gate still blockssudoand system-wide changes at this level.--skip-permissions-unsafe: removes droid's gate entirely and allows every operation. It cannot be combined with--auto.
That gate is droid's own. In a Tenki sandbox the guest VM is the safety boundary, and raising the level only changes what droid may do inside that guest. Commands in a session run as the unprivileged tenki user (uid 1000) with passwordless sudo, so once the gate is fully removed, droid can do anything in that VM. What it cannot reach is the host, other tenants' sessions, and the Tenki control plane, and the VM is disposable.
Pin an exact build
stable moves to each newly published build. When a workload has to stay on the exact build it was tested against, resolve the tag once and launch the snapshot reference it returns:
tenki sandbox registry resolve tenki/droid:stable
# image_id : <image-id>
# snapshot_id : <snapshot-id>
tenki sandbox create --image tenki/droid@<snapshot-id>A snapshot reference never moves, so it keeps launching that build after stable advances.