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

# Access rules

> Orgs, members and roles, share links, tokens, grants, and what agents may do

The exact rules for orgs, members, and sign-in, for looking things up. What a single command
does is in the [CLI reference](https://tesser.sh/docs/cli-reference.md), and timers and box sizes are
in [Configuration](https://tesser.sh/docs/config.md).

The [Teams](https://tesser.sh/docs/teams.md) page explains the ideas.

## Members, sharing, and sign-in

### Orgs

* `tesser login` asks which org to use when it matters, and
  `tesser login --org <id>` picks one. `tesser whoami` prints the signed-in
  email and the current org.
* An admin renames the org on the dashboard's Organization tab, with the
  pencil button beside its name. A name is 1 to 64 characters. The org id
  never changes, so `tesser org`, `TESSER_ORG`, tokens, and grants keep
  working.

### Members and roles

* A member added with `tesser member add` is a member at once. The 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. Signing in on the dashboard lands them in
  the org.
* `add` again with the same role resends the email. With a different role it
  fails; `tesser member role` changes a role.
* Admins manage members, service env values, and the warm pool, and can
  operate on any box in the org. Members create and use their own boxes, wake
  and `keep` the shared instances, and pin them with `--ensure-running`.
* The last admin cannot be demoted or removed.
* Service accounts, service account tokens, and grants are on the Team plan.
  Shared instances and the warm pool are on every plan.

### Box keys and share links

* `tesser status` shows the membership id that owns a box, and
  `tesser member ls` maps it to a person.
* A box carries the keys of its owner's laptops and 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.
* Opening a share link (or `tesser review <link>`) puts the teammate's key on
  the box and on the owner's boxes it depends on, never on the org's shared
  instances. The box appears at `box-<id>.localhost:<port>` on their laptop,
  and `tesser ssh` works.
* While the link lives, the teammate counts as another owner: `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
  (`tesser share --revoke`). Each takes the key and the access back.
* On Tesser's cloud, `tesser share` also prints a
  `https://box-<id>.tesser.review/` address that the org's members open in a
  browser while the link lives. The first visit signs them in at tesser.sh,
  and only active members get in. To serve shared boxes on your own domain
  for people without a Tesser account, set up a
  [share gateway](https://tesser.sh/docs/share-gateway.md).

### Commands an agent is refused

Any member can change any box in the org, but when a coding agent such as
Claude Code or Codex names a box you did not make (a teammate's box, a shared
instance, an unclaimed pool box), these are refused:

`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`,
  which the agent should run only when you asked it to use that box.
* The check runs before the box is woken, so a refused command never wakes or
  bills it.
* Commands that leave off the box id use the worktree's own box and are never
  refused. Read-only commands (`ls`, `status`, `logs`, `ssh`) are not
  checked, and neither are commands you type yourself in a terminal.

### Tokens

* A token comes from the dashboard (Your tokens on the Organization tab), or
  an admin mints one for a service account with `tesser member token create`.
* `tesser login --token tsr_api_… --org org_…` saves one.
* A token belongs to one org. Every token expires: 90 days from the
  dashboard, or whatever `--expires` said.
* `tesser logout` revokes the saved token and deletes it from disk.

### Grants

* A grant is a rule: OpenID Connect 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, made by admins, and always for a
  service account, never a person. The grant id is not a secret and can be
  committed.

  ```sh theme={"theme":"css-variables"}
  tesser grant create devin --pin org_id=<devin org id>   # 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 its 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 returns a
  token that lasts as long as the id token, an hour at most. The CLI proves
  again when it is about to expire.

* In a GitHub Actions job with `permissions: id-token: write`, the CLI mints
  the id token itself. For Devin and Replicas, the printed line carries
  `--proof '<command>'`, a command that prints an id token for `{audience}`;
  the CLI fills in the audience and reruns it whenever it needs a token.

* An SSH key added with an exchanged token is dropped from every box once the
  last token of its session (a GitHub run, a Devin session) expires or is
  revoked.

* `tesser grant rm` stops new exchanges.

### Grants and your own AWS account

When the org runs boxes in its own AWS account, the agent also needs AWS
credentials. Give the grant a role:

```sh 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.

### Who an agent's boxes belong to

* Boxes an agent session makes show as `devin · <session>`, 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`. GitHub Actions carries
  no email, so its `actor_id` only attributes through an alias.
* They show in that person's dropdown.
* Usage is metered per box-second and shown on the dashboard's Usage tab.


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