> ## Documentation Index
> Fetch the complete documentation index at: https://tesser.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Where your code goes

> Every hop your source takes, and what the control plane receives

Your worktree moves from your laptop to a box over SSH and nowhere else.
The control plane at `api.tesser.sh` receives ids, ports, and states. It
NEVER receives a file, a diff, terminal output, or your app's traffic. For
an org that [runs its boxes in its own AWS account](https://tesser.sh/docs/self-hosting.md), the code
exists in two places: your laptops and your account.

A [snapshot](https://tesser.sh/docs/boxes.md#snapshots) is the one copy that leaves the boxes: it
stores a builder box's home directory, with the checkout in it, in an S3
bucket. For an org in Tesserc's cloud that bucket is Tesserc's; for an org in
its own AWS account it is a bucket in that account.

```mermaid theme={"theme":"css-variables"}
flowchart LR
  laptop -- "ssh: rsync, git pack, exec, logs, tunnels" --> box
  laptop -- "https: ids, ports, states" --> cp[control plane]
  box -- "wss: alive, listening, exit code" --> cp
  box <-- "private VPC address, same org" --> box2[other box]
```

## Every hop

| What moves | How |
| - | - |
| Worktree files | rsync over SSH, laptop to box |
| The box's `.git` | a git pack over SSH, laptop to box |
| `exec` output | the SSH session's stdout and stderr |
| `logs` | `tail` of `~/.tesser/dev.log` over SSH |
| Browser traffic to a dev server | `ssh -L` tunnels held by the daemon |
| Env files | SSH stdin into a mode 600 file |
| A shared instance's checkout | a git pack over SSH, checked out on the box |
| One box's traffic to another | the org's private VPC addresses |
| Snapshots | HTTPS between the box and S3: in Tesserc's cloud over URLs the control plane signs for that box, in your own account with the boxes' role |

The control plane has no upload endpoint. A box's only channel to it is a
WebSocket whose upward messages are `hello`, `heartbeat`, and a short list
of events, none of which carries a file.

## The SSH connection

Each laptop has one ed25519 key pair, generated with `ssh-keygen` the
first time you sign in and stored beside your credentials in
`~/.config/tesser/`. The private half never leaves that directory. The
public half goes to the control plane once, on your membership, and the
control plane decides which boxes it belongs on: your own boxes, every
box if you are an org admin, every shared instance, a box a CI job or
hosted agent launched on your behalf, and a teammate's box while they
share it with you. A CI job or hosted agent that signs in through a grant
registers its own key, which lasts only as long as its token. boxd
receives that whole set over the box's WebSocket and writes it as `~/.ssh/authorized_keys`, replacing the file each time, so a
key that stops belonging there leaves it. sshd on the box accepts nothing
else: no password, no cloud-init key, no key the control plane did not
place.

Every `ssh` and `rsync` the CLI runs uses `IdentitiesOnly=yes` with that
key, `BatchMode=yes` so an agent never hits a prompt, and a per-box
`known_hosts` file with `StrictHostKeyChecking=accept-new`: the first
connection records the box's host key and every later one must match it.
Nothing touches your `~/.ssh`. Through Session Manager the host key is
filed under the instance id instead of an IP.

## What sync sends

`sync`, `exec`, and `dev` ship the files git would: tracked files plus
untracked files that are not ignored, as one explicit file list to rsync.
Ignored paths such as `node_modules`, `.env.local`, and build output stay
on the laptop unless the manifest's `env.files` names them. Removals are
exact paths from the previous list rather than `--delete`, so the box's own
build state survives.

The box's `.git` is built from your clone. The CLI remembers which refs
the box holds, packs only the git objects the box lacks, and streams the
pack over SSH into `git index-pack` on the box. A fresh box gets your
branch's commits since the default branch, plus the default branch's tip;
afterwards the CLI sends up to 100 older commits in the background. The box
never fetches from GitHub and has no git
credential.

A shared instance works the same way. `tesser make api --ensure-running <sha>` sends that commit as a pack and checks it out on the box; only the
files the manifest's `env.files` names ride rsync, from your worktree. The
control plane is told the sha, not the commit.

## What the control plane receives

* **Box metadata.** Ids, class, service name, size, owner, power state, IP
  addresses, and the commit sha of a shared instance.
* **Service manifests.** The TOML text of each manifest, which holds ports
  and the `setup` and `dev` commands and is committed to your repository.
* **Your public key**, on the way to the box.
* **boxd heartbeats and events.** Whether the dev server is running, its
  pid, exit code, which ports are listening, whether the health check
  passes, and how many SSH sessions are active. Events add when `setup`
  finished, the status and time of the first page the server answered, the
  sizes of `node_modules` and build caches, CPU, memory, and disk pressure,
  and the outcome of a boxd update.
* **Crash snapshots and the last log line.** When a dev server exits, boxd
  sends the last 40 lines of its output with the exit event so `tesser dev`
  can say why. While a dev server runs, boxd also reports the last line of
  its output, cut to 300 characters, and when the app crashes under a file
  watcher or another process holds its port, the last 20 lines. These are the
  only places program output reaches the control plane. An org in
  [its own AWS account](https://tesser.sh/docs/self-hosting.md) turns them off with
  `tesser cloud connect --no-crash-output`: the control plane then keeps the
  exit code and none of the output lines, and `tesser dev` points at
  `tesser logs`, which reads the log file over SSH.
* **Snapshot records.** Each snapshot's id, repository, commit sha, sizes,
  state, and, for a failed build, a short reason. The setup log stays on the
  builder box, and the image goes to the bucket.
* **Routing tables and wires.** Which box each dependency port points at.
* **Values set with `tesser env set`**, stored in the org and placed in the
  environment of the service's boxes and of workbenches from the same
  repository. An org in [its own AWS account](https://tesser.sh/docs/self-hosting.md) can keep them
  in its Parameter Store instead: the control plane then writes each value
  once, keeps the key's name, and never reads a value; the boxes read them
  themselves. Env files pushed to a dev box go over SSH and are not among
  them.
* **Usage.** When each box was awake, with its size, service, and owner.
* **API token hashes.**

Not on the list: file contents, diffs, commits, the output of `exec`,
`ssh`, or `logs`, HTTP traffic to a dev server, and the contents of any env
file that was pushed or synced.

## In a snapshot

A snapshot holds `/home/ubuntu`, `/var/lib/docker`, and
`/var/lib/containerd` from the builder box after every `setup` ran: the
checkout at the snapshot's commit, `node_modules` and other installed
dependencies, and whatever `setup` wrote. If `setup` writes a value from
`tesser env set` to disk, the snapshot holds it too. Before the capture, the builder deletes
the personal files listed under [Snapshots](https://tesser.sh/docs/boxes.md#snapshots), such as
`~/.ssh/authorized_keys`, `~/.git-credentials`, and `~/.aws`. Tesserc's
bucket blocks public access, encrypts at rest with SSE-S3, and refuses
requests not made over TLS. In Tesserc's cloud, boxes have no S3
credentials: the control plane signs a URL that expires within an hour for
each object a box reads or writes. In [your own AWS account](https://tesser.sh/docs/self-hosting.md#snapshots)
it is the reverse: boxes reach your bucket with the boxes' role, and the
role Tesserc assumes has no access to it.

## On the box

The worktree lives at `~/workspace` and the dev server's output at
`~/.tesser/dev.log`. boxd acts only when told to: start or stop the dev
server, rewrite its routing table, replace its authorized keys, set the
env for shells, mount a repo's snapshot when a pool box is claimed, and
update itself. It has no message for reading
a file.

A start cannot name the command. A start message names only the service:
boxd reads `setup` and `dev` from the `<service>.toml` in `~/workspace`,
the copy your own `tesser sync` or `tesser dev` put there, and runs those.
That guarantee covers starts and wakes, and nothing more:

* **Env** is the control plane's to set (it holds what you gave
  `tesser env set`). boxd drops keys that load a program, such as
  `NODE_OPTIONS`, `LD_PRELOAD`, `BASH_ENV`, and `PROMPT_COMMAND`, along
  with the `GIT_`, `NPM_CONFIG_`, and similar families. That list is a
  denylist, so it covers the known hooks rather than every program's.
* **A boxd update** carries a program. The control plane tells boxd to
  update, and boxd fetches a new bundle from the control plane and runs it
  in place of itself, but only a bundle that carries Tesserc's release
  signature; the first boot of a box checks the same signature. The control
  plane chooses which signed release runs, not what is in it.
* **`authorized_keys`** is the control plane's to write, which is how it
  decides who may ssh in.

The root volume is EBS encrypted. When a box sleeps, it hibernates and
writes its memory to that volume, so whatever your processes held in memory
stays encrypted on the box's own disk until it wakes. The instance's user-data holds no
credential: it is JSON naming the org, the box, and the control plane's
URL, and nothing executes it, because the image turns cloud-init's
user-data processing off and a boot step reads the JSON from the instance
metadata endpoint. That endpoint stays on for the life of the box, IMDSv2
only, because the box's AWS credentials come from it.

boxd proves which box it is with a token from AWS STS
`GetWebIdentityToken`: signed by AWS, valid for at most five minutes,
naming the instance and its account, and addressed to the control plane.
The control plane accepts a box's WebSocket only with a token naming that
box's instance. In Tesserc's account, minting that token is the only thing
the box's instance role can do. Any process on the box can mint one, so
code running on a box can speak to the control plane as that box: it
receives that box's routing table, env, and authorized keys, which are on
the box already, and nothing of any other box.

In Tesserc's account, the boxes of one org sit in a security group that
admits port 22 from anywhere and, from the org's own boxes, only port
14650, the port boxd forwards dependencies over. boxd
passes a connection on that port through only to a port the box's manifest
declares, so another box never reaches anything else your app or a test
listens on, and nothing reaches the group from another org. In your own
account there is no port 22: the group admits only 14650, from the org's
own boxes and from a [share gateway](https://tesser.sh/docs/self-hosting.md#serve-shared-boxes-on-your-own-domain)
if you run one. Box-to-box traffic stays on private VPC addresses.

## In your own AWS account

For a connected org, the instances, the disks, the code, the logs, and the
box-to-box traffic are all in your account, and Tesserc reaches it with a
short-lived OIDC token rather than a stored credential. Boxes launch from
Tesserc's published image, or from your own copy of it with the role pinned
to that copy, and never run their user-data.

There is no inbound port: the SSH stream, still encrypted end to end
between your laptop and sshd, rides inside a Session Manager session that
your IAM authorizes. [What the control plane can do](https://tesser.sh/docs/self-hosting.md#what-the-control-plane-can-do)
lists what it can still do to those boxes.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.