> Documentation index: https://docs.beetl.io/llms.txt

# Tenants and roles

> What a tenant contains, what each role can do, and where your data is stored.

Source: https://docs.beetl.io/concepts/tenants-and-roles/
Last updated: 2026-11-10

A tenant is one customer workspace. Your connections, datasets, pipelines, automations, apps, reports and query
results all live inside exactly one tenant, and nothing in Beetl crosses from one tenant to
another.

## How tenant scope works

Beetl never takes a tenant id from a request. Every call is scoped by who is making it: your
browser session after you sign in, or the API key an MCP client presents. That holds for every
surface, including Query, chat, MCP, dashboards and the sandboxes that run integration code.

Each user belongs to one tenant. Your email address is your login name and is unique across Beetl,
so one email cannot sign in to two tenants.

## What is shared and what is personal

Most of what you build belongs to the tenant, and every user in it sees the same thing:

* connections, syncs, File Sets and file processors
* datasets and pipelines
* automations, which run under a workspace identity rather than as the person who created them
* apps, reports, report templates and report documents

A few things belong to the person who created them:

* query results, which only their creator can open (automation evidence is open to everyone)
* chat sessions, including the assistant sidebar's history
* API keys for MCP

There is no sharing between users yet. You cannot send a colleague a link to a query result or a
chat.

## Roles

There are two roles: TenantAdmin and TenantUser.

A **TenantAdmin** manages the tenant's configuration. Only an admin can:

* add, edit, delete and test object stores, and choose the default one
* register and manage external sources (the PostgreSQL databases behind external datasets)
* set up AI (managed AI or your own key) and standing instructions for the assistant
* set up dashboards
* install, update and remove Connect packages (connection types)
* delete saved connection credentials

A **TenantUser** can do everything else, and so can an admin. That includes creating and running
connections and syncs, uploading File Sets, creating and configuring file processors, registering datasets, building and deploying
pipelines, creating automations, creating and running apps and reports, querying, chatting and creating API keys.

The admin pages sit under Settings → Tenant. A TenantUser can open Settings too, but only sees the
User tab, where API keys are managed.

### Adding users and changing roles

Beetl creates user accounts and assigns their role, and there is no invite flow in the app yet.
Every new tenant gets a first TenantAdmin when it is set up. To add a colleague or change
someone's role, contact Beetl.

## Where your data is stored

Beetl keeps the datasets it writes in S3-compatible object storage. Query results are kept in
Beetl's own storage, whichever store your datasets use.

### Beetl's hosted store

Every tenant comes with Beetl's hosted store, an object store registered when the tenant is set up.
Nothing else needs configuring before you can upload files or run pipelines.

In Settings → Tenant → Object storage, the store Beetl writes its own datasets to is marked
**Managed data**. The app calls this role "Beetl storage". A new tenant's hosted store has it from
the start.

### Use your own bucket

A TenantAdmin can add more stores, for example a bucket in your own cloud account. Choose Add
object store and enter:

* a name
* a base URL such as `s3://bucket/prefix`
* connection options as name and value pairs, such as the endpoint, region and access keys

Beetl tests every store before saving it: it writes an object, reads it back and deletes it. If
that fails, the store is not added and the error says why. Test access re-runs the same check on
a saved store at any time.

To make Beetl write new datasets to your bucket, choose **Use as Beetl storage** on it. Datasets
that already exist stay where they were written.

Any store can also be the source of [registered datasets](https://docs.beetl.io/sources/registered-datasets). Any user
can browse a store's files and register them as datasets, which Beetl then reads in place without
copying. This is how you bring in data that already sits in your own bucket.

### Rules for editing and deleting stores

* A store cannot be deleted while any dataset still uses it.
* The default store cannot be deleted while other stores exist. Make another one the default first.
* A store's base URL cannot change while any dataset uses it.
* Deleting a store only removes it from Beetl. The objects in the bucket are never deleted.

If a tenant ever has no object store at all, anything that writes data fails with
`OBJECT_STORE_NOT_CONFIGURED`, and the app shows a notice that links admins to Settings and tells
everyone else to ask an admin.

## Related

* [AI settings](https://docs.beetl.io/concepts/ai-settings) for the AI options an admin chooses
* [Datasets and tiers](https://docs.beetl.io/concepts/datasets-and-tiers) for what is stored and how
* [Security](https://docs.beetl.io/security) for how tenants are kept apart and how sign-in works
