# Pi auth on sandboxes

How pi gets LLM creds and a model when it runs on a sandbox — the detached path ([daytona runtime](./sandbox-daytona.md), legacy [sandbox-sprite](sandbox-sprite.md)) 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](pi.md)) and reaches the sandbox only through the `run_command` tool. Decisions, not mechanics — wire-up lives in [environments](environments.md), [secrets](secrets.md).

## 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](./llm-keys.md).
3. **Setup is three commands.** `arbe sandbox setup`, `arbe secret set`, `arbe env create --secret` — see "Typical setup workflow" in [runtime](./runtime.md).

## 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](dispatch.md) · [environments](environments.md) · [secrets](secrets.md) · [sandbox-sprite](sandbox-sprite.md) · [pi](pi.md)
