Skip to content
View as .md

Pi auth on sandboxes

How pi gets LLM creds and a model when it runs on a sandbox — the detached path (daytona runtime, legacy sandbox-sprite) and manual arbe x. In-process bot dispatch does not run pi on the sandbox; it replies via pi-ai with OpenRouter by default (pi) and reaches the sandbox only through the run_command tool. Decisions, not mechanics — wire-up lives in environments, secrets.

Decisions

  1. Creds live in arbe secret. Environments bind names; values forward as set -lx env vars into the per-turn fish -lc. Env-var keys only — OAuth (Anthropic Pro, OpenAI Codex, …) is v2.
  2. OpenRouter is the canonical sandbox credential. Store and bind OPENROUTER_API_KEY; pi receives it as an env var, no persistent pi login on the sandbox. Provider-specific keys (ANTHROPIC_API_KEY, OPENAI_API_KEY, …) work when paired with an explicit model. Default model is defaultModelRef (packages/core/pi/defaults.ts) — a pinned cheap OpenRouter ref, not openrouter/auto. See llm-keys.
  3. Setup is three commands. arbe sandbox setup, arbe secret set, arbe env create --secret — see “Typical setup workflow” in runtime.

Failure narration

Pi auth/billing/quota errors are hoisted into a signal.thread.pi_failed entry alongside the failed status flip. Carries errorClass (auth / billing / quota / network / pi_exit / unknown), a short message, and provider/model when known. Additive — the pi.assistant payload is unchanged. Source: decidePiOutcome (packages/sandbox/src/daytona/decide-pi-outcome.ts) + classifyProviderError (packages/sandbox/src/provider-error.ts).

Open

  • CLI’s ~/.config/arbe/sandboxes/<name>.env overlaps with arbe secret; not yet retired.
  • OAuth providers — needs caller-managed credential storage and per-sandbox refresh.

See also

dispatch · environments · secrets · sandbox-sprite · pi