---
title: "Workspace"
description: "The tenant. Everything belongs to exactly one, and nothing crosses between them."
url: "https://saved.sh/docs/concepts/workspaces"
---

A **workspace** is the top-level tenant. Members, permissions, workers, backups, artifacts,
quotas and billing all belong to one, and nothing crosses between workspaces.

It is flat. There is no organization above a workspace and no project below it.

## What a workspace owns [#what-a-workspace-owns]

| Owned                        | Notes                                     |
| ---------------------------- | ----------------------------------------- |
| Members and their roles      | A person may belong to several workspaces |
| Backups, runs and artifacts  | Never shared                              |
| Workers and API keys         | Bound at creation, cannot be moved        |
| Destinations and connections | Linked once, selected per backup          |
| Quotas and billing           | One subscription, one set of limits       |
| The audit trail              | Queried by workspace, always              |

## One credential, one workspace [#one-credential-one-workspace]

**A credential is scoped to exactly one workspace.** There is no token that spans two and no
header that selects one.

| Credential     | How it is scoped                    |
| -------------- | ----------------------------------- |
| Your session   | Re-minted when you switch workspace |
| An API key     | Bound at creation                   |
| A worker token | Bound at provisioning               |

```bash
sctl workspace list
sctl workspace switch <workspace-id>
sctl workspace current
```

Switching is a real re-authentication, not a filter. That is what makes the boundary a
property of the credential rather than something we remember to apply.

<Callout>
  A workspace ID appearing in a URL is not a selector: it must match your credential's
  workspace. Another workspace's ID returns an error, never data.
</Callout>

## Identity is global, access is per-workspace [#identity-is-global-access-is-per-workspace]

You have one identity. Access is granted per workspace through a **membership**, and the
membership is what a role attaches to.

```
you ──membership(admin)──► acme
    ──membership(member)──► analytics
```

The practical consequence: commands take a **membership ID**, not your user ID, when changing
what someone can do. The same person can be an admin in one workspace and have no access in
another.

## Roles [#roles]

| Role     | Carries                 |
| -------- | ----------------------- |
| `admin`  | Every permission        |
| `member` | **Nothing**, by default |
| Custom   | Whatever you grant      |

<Callout type="warn">
  A bare `member` sees an empty workspace and can do nothing. That is deliberate, so nobody is
  granted access by simply existing. Assign a role when you invite, or expect a follow-up
  question.
</Callout>

Roles bundle permissions; the enforcement atom is the **permission**. See
[Permissions](/docs/security/permissions).

## Creating one [#creating-one]

```bash
sctl workspace create "analytics"
```

The creator becomes `admin`. Creating a workspace is **human-only**: a machine credential is
refused, because a workspace that does not exist yet has no permission to check against.

A new workspace starts on trial, with credit against real usage and no card required.

## When to use more than one [#when-to-use-more-than-one]

Use a second workspace when the **blast radius** should be different, not merely to organise
things.

| Reason                                        | Second workspace?                  |
| --------------------------------------------- | ---------------------------------- |
| Separate production from staging credentials  | **Yes**                            |
| Separate clients whose data must not mix      | **Yes**                            |
| Different people should see different backups | **Yes**, roles cannot hide backups |
| Different retention per backup                | No. Retention is per backup        |
| Tidier naming                                 | No. Name the backups               |

The third row is the one people get wrong. Permissions are workspace-wide: a member with
`backups:read` sees **all** the workspace's backups. There is no per-backup access control, so
if some backups must be invisible to some people, that is a workspace boundary.

## Limits [#limits]

| Limit                 | Trial | Paid |
| --------------------- | ----- | ---- |
| Workspaces per user   | 5     | 5    |
| Members per workspace | 1     | 25   |

## Billing states [#billing-states]

A workspace's billing state gates writes but **never reads**.

| State                       | New runs | Config changes | Reads and downloads |
| --------------------------- | -------- | -------------- | ------------------- |
| `trial`, `active`, `warned` | Yes      | Yes            | Yes                 |
| `stopped`                   | No       | Yes            | Yes                 |
| `blocked`                   | No       | No             | Yes                 |

<Callout>
  Downloads keep working in every state. A workspace behind on payment can still read and
  retrieve every artifact it has. Your backups are not leverage.
</Callout>

## Next [#next]

<Cards>
  <Card href="/docs/concepts/quotas" title="Quotas" description="What a workspace is allowed to hold." />

  <Card href="/docs/cli/workspaces" title="Managing workspaces" description="Members, invitations and roles." />

  <Card href="/docs/security/permissions" title="Permissions" description="What a role actually grants." />
</Cards>
