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

# Teams & API keys

> How teams, roles, and API keys are structured across an Octavia workspace.

Everything you build with Octavia belongs to a **team**, and every call is made with an
**API key** that belongs to that team. This page explains how those two fit together,
and which key to use where.

<Info>
  Creating and rotating keys happens in the dashboard. This page explains the model
  behind it. For the click-by-click version, see [API keys](/api-reference/ai-cms/apikeys).
</Info>

***

## Teams

A team is the unit of isolation. Its members, its API keys, its content, and its
usage are all separate from every other team's.

**Your first team is created for you at sign-up**, named after you. From the team
switcher in the dashboard you can create more, and you can have keys and apps in
several at once.

| **Concept** | **What it means**                                            |
| ----------- | ------------------------------------------------------------ |
| **Team**    | The container. Owns keys, content, and usage.                |
| **User**    | A person with dashboard access. Can belong to several teams. |
| **Role**    | What a user — or a key — is allowed to do.                   |
| **API key** | A credential scoped to one team **and** one service.         |

<Note>
  Keys are scoped to a team *and* a service. A key you create for Storage never counts
  against your AI CMS key allowance, and you can revoke one without touching the
  other.
</Note>

***

## Roles

Roles come in two flavours, and it is worth keeping them apart.

**User roles** decide what a person can do in the dashboard — invite teammates, manage
billing, rotate keys.

**Key roles** decide what a credential can do against the API. This is the list that
matters when you are writing an integration:

| **Role**            | **Can do**                                                   | **Typical use**                             |
| ------------------- | ------------------------------------------------------------ | ------------------------------------------- |
| **Read-only**       | Read published content, media, categories, translations.     | Public sites, CDN cache warming, analytics. |
| **Writer**          | Create and edit own drafts, upload media, submit for review. | Contributor tools.                          |
| **Editor**          | Create, edit and localize articles; review submissions.      | Editorial back office.                      |
| **Publisher**       | Handle publishing, scheduling and visibility.                | Release pipelines.                          |
| **Managing Editor** | Approve and publish, manage categories and translations.     | Editorial leads.                            |
| **Admin**           | Manage content, translations and team members.               | Team administrators.                        |
| **Super Admin**     | Unrestricted access, including billing and API keys.         | Trusted backend systems only.               |

<Warning>
  A key that authenticates successfully can still be rejected with <code>403</code> if
  its role lacks permission for that operation. **Authentication and authorization
  are separate checks** — a valid key is not automatically a permitted one.
</Warning>

<Tip>
  Start at the lowest role that covers the use case and raise it when a call actually
  fails with <code>403</code>. Most public-facing reads never need more than
  **Read-only**.
</Tip>

***

## Choosing a key for a job

The most useful thing you can do is give each system its own key. Then a leak, a
rotation or a mistake is contained.

| **System**                     | **Role**    | **Why**                                            |
| ------------------------------ | ----------- | -------------------------------------------------- |
| **Public website**             | Read-only   | It only reads published content.                   |
| **Server-side render / cache** | Read-only   | Nothing it does should ever write.                 |
| **Back office / editor tool**  | Editor      | Authors and editors need to write, not to publish. |
| **Content pipeline**           | Publisher   | It publishes, so it needs publishing rights.       |
| **Migration or import job**    | Super Admin | Only while the job runs — narrow it afterwards.    |

```bash theme={null}
export OCTAVIA_API_KEY="sk_live_..."   # read from your secret store
```

<Note>
  Keys can be given an expiration date or a lifetime with no expiry, and can be
  disabled and re-enabled without being deleted. See [API
  keys](/api-reference/ai-cms/apikeys).
</Note>

***

## Keeping a key safe

A key in client-side code — a browser bundle, a mobile app, a public repository — is
a compromised key. **Call Octavia from your server only.**

* **Read it from the environment.** Never hardcode it.
* **Never commit it.** Keep it in your deployment platform's secret store.
* **Rotate on a schedule**, and immediately if it is ever exposed.
* **Use the dashboard's last-used timestamps** to find keys nothing is using any more,
  then revoke them.

<Warning>
  Disabling a key takes effect immediately across every client using it, so rotate
  before you revoke when a running service depends on it.
</Warning>

***

<CardGroup cols={2}>
  <Card title="API keys" icon="key-round" href="/api-reference/ai-cms/apikeys" arrow="true">
    Create, edit, disable and revoke keys in the dashboard.
  </Card>

  <Card title="Authentication" icon="shield" href="/api-reference/ai-cms/authentication" arrow="true">
    How the key is sent, and how multi-tenancy works.
  </Card>
</CardGroup>
