> ## 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.

# Invite teammates and share a running branch

> How orgs work, how a teammate joins, and how agents and CI sign in

Everything in Tesserc belongs to an org. An org can be just you, or several
people; either way the boxes, the shared instances, and the service
names all live in it together. An account can belong to
more than one org, and `tesser login` asks which one to use when it matters.

## Orgs on this laptop

```sh theme={"theme":"css-variables"}
tesser org            # print the org every command runs in
tesser org ls         # list the orgs this laptop is signed in to
tesser org use <id>   # make a different one the default
tesser login --org <id>
```

Setting `TESSER_ORG=<id>` for a command uses that org for that command only.
`tesser whoami` prints the signed-in email and the current org.

An admin renames the org on the Organization tab of the
[dashboard](https://tesser.sh/dashboard), with the pencil button beside its
name. A name is 1 to 64 characters. The org id stays the same, so `tesser
org`, `TESSER_ORG`, tokens, and grants keep working.

## Adding a teammate

An admin runs:

```sh theme={"theme":"css-variables"}
tesser member add them@example.com
```

They are a member from that moment. That address gets an email from
[noreply@tesser.sh](mailto:noreply@tesser.sh) naming the org, with a link to the dashboard and the
install line. The next time that person runs `tesser login`, the browser
offers them the org; signing in on the dashboard lands them in it. Running
`add` again with the same role resends the email; with a different role it
fails, and `tesser member role` changes it. The Organization tab on the [dashboard](https://tesser.sh/dashboard)
does the same thing through a form.

There are two roles, admin and member. Admins manage members, service env values, and the warm
pool, and they can operate on any box in the org. Members create and use
their own boxes, wake and `keep` the shared instances, and pin them to a
commit with `--ensure-running`. The last remaining
admin cannot be demoted or removed.

```sh theme={"theme":"css-variables"}
tesser member ls
tesser member role <membership_id> admin
tesser member rm <membership_id>      # also revokes every token that person holds
```

## Seeing each other's boxes

`tesser ls` lists every box in the org, including teammates' boxes, and
`tesser status` shows the membership id that owns a given box (`tesser
member ls` maps it to a person). A box carries the keys of its owner's
laptops and of the org admins; a box an agent or CI job made for someone
carries that person's keys too, and a shared instance carries every
member's. Nobody else's key is on it until it is shared. To let a teammate
look at one, its owner runs `tesser share <box_id>` and sends the link.
The teammate opens it (or runs `tesser review <link>`), the control plane
puts their key on the box and on the boxes of yours it depends on (never
on the org's shared instances), and it
appears at `box-<id>.localhost:<port>` on their laptop, with `tesser ssh`
for a shell. They see the box as it is, uncommitted changes included, and
they count as another owner of it while the link lives: `sync`, `dev`,
`wire`, `sleep`, and `rm` all work, so a `sync` from their worktree
overwrites the author's. Links expire, die with the box, and can be
revoked; each of those takes the key and the access back. This is how a
pull request gets reviewed against the author's running box.

Any member can change any box in the org, but the CLI stops a coding agent
such as Claude Code or Codex from doing it by mistake. When an agent names a
box that you did not make, such as a teammate's box, a shared instance, or an
unclaimed pool box, Tesserc refuses these commands: `rm`, `sync`, `exec`,
`dev`, `sleep`, `keep` (including `--off`), `sleep-after --box`, `env push`,
`wire <box_id> <service> <target_box_id>`, `share --revoke`, and
`boxd update`. The error says whose box it is and prints the same command
with `--yes` added, which the agent should run only when you asked it to use
that box. The check happens before the box is woken, so a refused command
never wakes or bills it. Commands that leave the box id off use the
worktree's own box and are never refused, and commands that only read, such
as `ls`, `status`, `logs`, and `ssh`, are not checked. Commands you type
yourself in a terminal are not checked either.

On Tesserc's cloud, `tesser share` also prints a
`https://box-<id>.tesser.review/` address that the org's members open in a
browser for as long as the link lives. The first visit sends them to
tesser.sh to sign in with their Tesserc account, and only active members of
the org get in. Nothing needs to be set up for this. To open shared boxes on
your own domain instead, for people without a Tesserc account, set up a
[share gateway](https://tesser.sh/docs/share-gateway.md).

What a team shares without any link are the shared instances, such as one
`api` at main that everyone's boxes connect to. See
[Connect a frontend to a backend](https://tesser.sh/docs/wiring.md).

## Tokens

A laptop signs in through the browser. A machine without a browser uses a
token created on the dashboard under Your tokens on the Organization tab, or one an admin
mints for a service account with `tesser member token create`:

```sh theme={"theme":"css-variables"}
export TESSER_TOKEN=tsr_api_…
export TESSER_ORG=org_…
tesser make api --ensure-running "$GITHUB_SHA"
```

You can also save such a token once with
`tesser login --token tsr_api_… --org org_…`. Tokens belong to one org, so a
token created in org A is not valid in org B, and every token expires (90
days from the dashboard; whatever `--expires` said). `tesser logout` revokes
the saved token and deletes it from disk.

## Agents and CI

An agent platform or a CI job that can prove who it is with an OpenID
Connect id token needs no stored secret. A grant is a rule: id tokens from
one issuer whose claims match the grant's pins may be exchanged for a
tesser token acting as one service account. Grants are org-level, admins
make them, and they are always for a service account, never for a person.
The grant's id is not a secret and can be committed.

```sh theme={"theme":"css-variables"}
tesser grant create devin --pin org_id=<devin org id>   # acts as the service account "devin", made if missing
tesser grant create replicas --pin organization_id=<replicas org id>
tesser grant create github:acme/web --pin ref=refs/heads/main
```

Each prints the id and the `tesser login oidc --org org_… --grant grt_…`
line to run where the issuer is. The CLI gets an id token with the control
URL as its audience, the control plane checks it against the issuer's keys
and the pins, and hands back a token that lasts as long as the id token, an
hour at most; the CLI proves again when that token is about to expire.
An SSH key added with that token is dropped from every box once the last
token of its session (a GitHub run, a Devin session) expires or is revoked.
Inside a GitHub Actions job with `permissions: id-token: write` the CLI
mints the id token itself:

```yaml theme={"theme":"css-variables"}
permissions:
  id-token: write
steps:
  - run: curl -fsSL https://tesser.sh/install | sh
  - run: tesser login oidc --org org_… --grant grt_…
```

For Devin and Replicas the printed line carries `--proof '<command>'`, a
command that prints an id token for `{audience}`. The CLI fills that in with
the audience it needs a token for, and reruns the command whenever it does.

If the org runs boxes in its own AWS account, the agent also needs AWS
credentials to reach them. Give the grant a role and the CLI handles that
too:

```bash theme={"theme":"css-variables"}
tesser grant create devin --pin org_id=<devin org id> --aws-role arn:aws:iam::<account>:role/<role>
```

The role trusts the same issuer for `sts:AssumeRoleWithWebIdentity`, with
`sts.amazonaws.com` as the audience and conditions matching the pins, and
allows Session Manager to the org's boxes. `tesser login oidc` assumes it with
the same proof command for that audience, writes AWS profile `tesser-<org>` with a `credential_process`
that proves and assumes again whenever AWS asks, and makes it the profile the
CLI uses for the org's boxes. Assuming the role never asks tesser, so
`tesser grant rm` does not end AWS access; changing the role's trust policy
does.

Boxes an agent session makes show as `devin · <session>` and are recorded as
made for the person who started the session: their email from the id token,
or an alias an admin set with `tesser member alias set` (Actions carries no
email, so its `actor_id` only ever attributes through an alias). They show in that person's dropdown. `tesser grant rm` stops new
exchanges.

A person who wants an agent to act as themselves does not need a grant: they
paste their own token into it, `tesser login --token tsr_api_…` or
`TESSER_TOKEN`, minted on the dashboard.

Usage is metered per box-second and shown on the dashboard's Usage tab.

Service accounts, service account tokens, and grants are part of the Team
plan. Shared instances and the warm pool are available on every plan.


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