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

# Tenancy

> Design secure multi-customer integrations with environments, tenants, knowledge bases, and external subjects.

AutoSage uses a strict resource hierarchy. Each level is both an ownership boundary and an isolation boundary for the resources below it.

## The hierarchy

```
Organization
  └── Environment                 API key boundary
        └── Tenant                Customer, credits, and quota boundary
              └── Knowledge base  Retrieval boundary
                    ├── Documents
                    ├── Agents
                    └── Chats
```

<AccordionGroup>
  <Accordion title="Organization" icon="building">
    The top-level account for billing, members, roles, and environments. Organization administration normally uses an authenticated user session.
  </Accordion>

  <Accordion title="Environment" icon="layer-group">
    An isolated deployment context such as development, staging, or production. Every API key belongs to exactly one environment and cannot reach another one.
  </Accordion>

  <Accordion title="Tenant" icon="box">
    The resource owner for a customer or project. A tenant has its own credit pool, quotas, knowledge bases, and data. In a multi-customer product, create one tenant per customer.
  </Accordion>

  <Accordion title="Knowledge base" icon="book">
    The retrieval boundary for documents, connected data, agents, and chats. Documents are indexed in a private partition for that knowledge base.
  </Accordion>
</AccordionGroup>

See [Core concepts](/product/concepts) for the product-level view of these objects.

## How API keys narrow access

An API key always belongs to one environment. Its optional resource lists determine what it can reach inside that environment:

| Key setting                   | Behavior                                                        |
| ----------------------------- | --------------------------------------------------------------- |
| `tenant_ids: []`              | Access every tenant in the key's environment, subject to scopes |
| `tenant_ids: ["..."]`         | Access only the listed tenants                                  |
| `knowledge_base_ids: ["..."]` | Narrow access further to the listed knowledge bases             |

<Warning>
  `admin:full` satisfies required scopes, but populated tenant and knowledge-base allowlists still constrain access when a specific resource is resolved. Tenant listing is the exception: an `admin:full` key can discover every tenant in its environment. Reserve it for trusted server-side provisioning. See [Access & scopes](/developers/concepts/access-scopes).
</Warning>

## The multi-customer pattern

Use two levels of isolation in a customer-facing application:

1. Create one **tenant per customer account** to separate data, credits, and quotas.
2. Pass a stable **`external_subject_id` per end user** to separate chat ownership and durable memory inside that tenant.

For example, a support platform could map customer account `acme` to one tenant, then use the application's own stable user IDs as external subjects:

```
Tenant: acme
  ├── external_subject_id: user_1042
  └── external_subject_id: user_7819
```

<Steps>
  <Step title="Create a tenant for the customer">
    ```bash theme={null}
    curl -X POST "https://api.autosage.ai/api/v1/tenants" \
      -H "Authorization: Bearer $AUTOSAGE_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "environment_id": "ENVIRONMENT_ID",
        "name": "Acme",
        "external_id": "acme"
      }'
    ```
  </Step>

  <Step title="Create a chat for an end user">
    ```bash theme={null}
    curl -X POST "https://api.autosage.ai/api/v1/chats" \
      -H "Authorization: Bearer $AUTOSAGE_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "id": "CHAT_UUID",
        "tenant_id": "ACME_TENANT_ID",
        "knowledge_base_id": "KB_ID",
        "model": "MODEL_ID",
        "external_subject_id": "user_1042",
        "message": "What is covered by my plan?"
      }'
    ```
  </Step>

  <Step title="Keep passing the same subject">
    Include `external_subject_id=user_1042` whenever you list, read, update, or continue that API-key-owned chat. A chat created for one external subject cannot be accessed as another subject.
  </Step>
</Steps>

<Tip>
  Use a small, workload-based set of API keys per environment, not one key per customer. For example, keep provisioning and runtime permissions on separate keys. Tenants isolate customer resources; stable external subjects isolate individual users' conversations and memories.
</Tip>

## Next steps

<CardGroup cols={2}>
  <Card title="Access & scopes" icon="shield-halved" href="/developers/concepts/access-scopes">
    Give each API key only the permissions and resources it needs.
  </Card>

  <Card title="Tenant API" icon="code" href="/developers/api/tenants">
    Create tenants and configure their quotas and memory settings.
  </Card>
</CardGroup>
