# Overview

> For the complete documentation index, see [llms.txt](/llms.txt)

A **box** is a hosted unotest installation for one organisation. It runs
the same viewer you use locally, in front of your own environments, and
adds what a team needs around it: sign-in with your identity provider,
roles, seats, an audit trail, scheduled runs and a place for CI to push
suites to.

Your tests never leave your repository except by your own action: a box
holds no credential to your code and never pulls anything. Suites reach it
through [`bundle push`](/box/pushing-suites/).

## What is inside

| Component | What it does |
|---|---|
| **Guard** | Sign-in, roles, seats, the licence check, the administration pages and the audit trail. Every request to the box passes through it. |
| **Viewer** | One viewer per environment, in a container of its own. The same UI as `npx @unotest/web viewer`, with the controls your role does not permit greyed out. It sees the environment's bundle and run history and nothing else of the box. |
| **Run sidecar** | The only component that holds the docker socket. Every run — ordered from the viewer, from CI, or by a schedule — and every bundle's `npm ci` executes in a throwaway container it starts for that one job. |
| **Daemon** | Stores pushed bundles, holds each environment's values and secrets, runs the per-environment queue and the schedules, and answers CI. It executes none of your code: it asks the sidecar for a container. |
| **Updater** | Keeps the box on the `stable` release channel, verifying every artifact before it is installed and rolling back if the stack does not come up healthy. |

## Projects and environments

A box serves one or more **projects**, each with one or more
**environments** (`test`, `staging`, `prod`, …). An environment has a
**target** — the URL the tests run against, injected into every run as
`APP_BASE_URL` — plus its own variables, secrets, run history, queue and
viewer. Which environments exist is decided in the box's configuration,
which unotest maintains with you; a pushed suite cannot create or rename
one.

Pull requests can get environments of their own (`pr-<n>`), created and
removed automatically when a project has preview deployments — see
[Pushing suites](/box/pushing-suites/#pull-request-environments).

## Where your code runs

Nothing of your suite executes next to the box's own state. A run gets a
container of its own: the bundle's files read-only, the environment's run
history read-write, the target, variables and secrets of that one
environment — and no view of the daemon, of other environments, of tokens
or of channel credentials. The container is gone when the run is over. A
bundle's `npm ci` runs the same way, so a dependency's install script
builds a native module without touching the box. The viewer of an
environment is a long-lived container on a network shared only with the
guard and the daemon, with no route out of the box.

Two consequences for the UI on a box: **editing a suite's files is not
available** — the sources are read-only there, and a push is what changes
them (such edits never survived the next `bundle push` anyway) — and
**Debug** cannot attach to a run, which lives in a container the viewer
has no path into. Details in [Security model](/box/security/#where-code-runs).

## What you receive

When unotest provisions a box for you:

- **A domain** — `https://tests.example.com`, or a name under your own
  domain. Sign-in redirects, the CI webhook and the viewer all live there.
- **A licence** — signed, with your organisation's name, a **seat count**
  and an expiry date. Seats are counted against people who have signed in
  recently; see [Sign-in](/box/sign-in/#seats).
- **Project tokens** — for `bundle push` and CI, one per project. Tokens
  that may also write environment values are minted separately.

You provide the identity-provider details (an OAuth client, and for Google
Workspace a directory service account) and the mapping from your groups to
roles. Nothing about your Workspace is stored anywhere but on your box.

## Roles

Two roles exist:

- **admin** — run tests, open the terminal, switch an environment's
  bundle, administer users, see and set environment values.
- **readonly** — browse scenarios, runs and results. Run and the terminal
  are unavailable, and the proxy refuses them regardless of what the UI
  shows.

Roles come from your directory groups, and an administrator can pin one on
the box. Details in [Sign-in](/box/sign-in/) and
[Administration](/box/administration/).

## Next

- [Sign-in](/box/sign-in/) — SSO, groups → roles, break-glass, seats
- [Administration](/box/administration/) — users, sessions, the audit trail
- [Environments & values](/box/environments-and-values/) — targets, variables, secrets
- [Pushing suites](/box/pushing-suites/) — `bundle push` from a laptop or CI
- [Schedules & queue](/box/schedules-and-queue/)
- [Security model](/box/security/)
- [Troubleshooting](/box/troubleshooting/)
